unit Sparkle.InProc.Server;

interface

uses
  Generics.Collections,
  Bcl.Utils,
  Sparkle.HttpServer.Dispatcher;

type
  TInProcServerManager = class;

  TInProcHttpServer = class
  strict private
    class var
      FServerManager: TInProcServerManager;
  strict private
    FDispatcher: THttpDispatcher;
  public
    const DefaultServerName = 'default';
  public
    class function ServerManager: TInProcServerManager;
    class function Default: TInProcHttpServer; static;
    class procedure Remove(const ServerName: string); static;
    class function Get(const ServerName: string): TInProcHttpServer; static;
    class function Find(const ServerName: string): TInProcHttpServer; static;
    class destructor Destroy;
  public
    constructor Create;
    destructor Destroy; override;
    property Dispatcher: THttpDispatcher read FDispatcher;
  end;

  TInProcServerManager = class
  strict private
    FServers: TDictionary<string, TInProcHttpServer>;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Remove(const ServerName: string);
    function Get(const ServerName: string): TInProcHttpServer;
    function Find(const ServerName: string): TInProcHttpServer;
  end;

implementation

uses
  System.SysUtils;

{ TInProcHttpServer }

constructor TInProcHttpServer.Create;
begin
  FDispatcher := THttpDispatcher.Create;
end;

class destructor TInProcHttpServer.Destroy;
begin
  FServerManager.Free;
end;

class function TInProcHttpServer.Default: TInProcHttpServer;
begin
  Result := ServerManager.Get(TInProcHttpServer.DefaultServerName);
end;

destructor TInProcHttpServer.Destroy;
begin
  FDispatcher.Free;
end;

class function TInProcHttpServer.Find(
  const ServerName: string): TInProcHttpServer;
begin
  Result := ServerManager.Find(ServerName);
end;

class function TInProcHttpServer.Get(const ServerName: string): TInProcHttpServer;
begin
  Result := ServerManager.Get(ServerName);
end;

class procedure TInProcHttpServer.Remove(const ServerName: string);
begin
  ServerManager.Remove(ServerName);
end;

class function TInProcHttpServer.ServerManager: TInProcServerManager;
begin
  if FServerManager = nil then
    FServerManager := TInProcServerManager.Create;
  Result := FServerManager;
end;

{ TInProcServerManager }

constructor TInProcServerManager.Create;
begin
  FServers := TObjectDictionary<string, TInProcHttpServer>.Create([doOwnsValues]);
end;

destructor TInProcServerManager.Destroy;
begin
  FServers.Free;
  inherited;
end;

function TInProcServerManager.Find(const ServerName: string): TInProcHttpServer;
begin
  if not FServers.TryGetValue(LowerCase(ServerName), Result) then
    Result := nil;
end;

function TInProcServerManager.Get(const ServerName: string): TInProcHttpServer;
begin
  Result := Find(ServerName);
  if Result = nil then
  begin
    Result := TInProcHttpServer.Create;
    FServers.Add(LowerCase(ServerName), Result);
  end;
end;

procedure TInProcServerManager.Remove(const ServerName: string);
begin
  FServers.Remove(LowerCase(ServerName));
end;

end.
