unit Main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, Winapi.ShellApi,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls, Vcl.ExtCtrls, System.Generics.Collections, System.IniFiles,
  Auth.Service, Auth.Server.Module, Api.Server.Module, App.Server.Module,
  ExeInfo, Api.Service, Ws.Server.Module, Ws.Service;

type
  TFMain = class(TForm)
    memoInfo: TMemo;
    btnApiSwaggerUI: TButton;
    btnExit: TButton;
    initTimer: TTimer;
    btnAuthSwaggerUI: TButton;
    ExeInfo1: TExeInfo;
    procedure btnApiSwaggerUIClick(Sender: TObject);
    procedure btnExitClick(Sender: TObject);
    procedure ContactFormData(AText: String);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure initTimerTimer(Sender: TObject);
    procedure btnAuthSwaggerUIClick(Sender: TObject);
  strict private
    procedure StartServers;
    function LogValue(const LabelName: string; const Value: string; FromIni: Boolean): string;
  private
    function LocalBrowserUrl(const Url: string): string;
  end;

var
  FMain: TFMain;

implementation

uses
  Common.Logging,
  Common.Config,
  Common.Ini,
  Sparkle.Utils,
  Api.Database,
  System.StrUtils;

{$R *.dfm}

{ --- Event Handlers --- }

procedure TFMain.btnExitClick(Sender: TObject);
begin
  Close;
end;

function TFMain.LocalBrowserUrl(const Url: string): string;
begin
  Result := StringReplace(Url, '://0.0.0.0:', '://localhost:', [rfIgnoreCase]);
end;

procedure TFMain.btnApiSwaggerUIClick(Sender: TObject);
var
  url: string;
begin
  url := TSparkleUtils.CombineUrlFast(ApiServerModule.XDataServer1.BaseUrl, 'swaggerui');
  ShellExecute(Handle, 'open', PChar(LocalBrowserUrl(url)), nil, nil, SW_SHOWNORMAL);
end;

procedure TFMain.btnAuthSwaggerUIClick(Sender: TObject);
var
  url: string;
begin
  url := TSparkleUtils.CombineUrlFast(AuthServerModule.XDataServer.BaseUrl, 'swaggerui');
  ShellExecute(Handle, 'open', PChar(LocalBrowserUrl(url)), nil, nil, SW_SHOWNORMAL);
end;

procedure TFMain.ContactFormData(AText: String);
begin
  if memoInfo.CanFocus then
    TThread.Queue(nil, procedure begin memoInfo.Lines.Add(AText); end)
  else
    TThread.Synchronize(nil, procedure begin memoInfo.Lines.Add(AText); end);
end;

procedure TFMain.initTimerTimer(Sender: TObject);
begin
  initTimer.Enabled := False;
  Caption := Caption + ' ver ' + ExeInfo1.FileVersion;
  ServerConfig := TServerConfig.Create;
  LoadIniEntries;
  LoadServerConfig;
  StartServers;
end;

procedure TFMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  ServerConfig.Free;
  IniEntries.Free;
  AuthServerModule.Free;
  ApiServerModule.Free;
  AppServerModule.Free;
  WsServerModule.Free;
end;

{ --- Helpers --- }

function TFMain.LogValue(const LabelName: string; const Value: string; FromIni: Boolean): string;
begin
  Result := LabelName + ': ' + Value + IfThen(FromIni, ' [from ini]', ' [default]');
end;

procedure TFMain.StartServers;
begin
  Logger.Log(1, '');
  Logger.Log(1, '*******************************************************');
  Logger.Log(1, '*                  emiMobile Server                   *');
  Logger.Log(1, Format('*               Version: %s', [FMain.ExeInfo1.FileVersion]));
  Logger.Log(1, '*            Developed by EM Systems, Inc.            *');
  Logger.Log(1, '*******************************************************');
  Logger.Log(1, '');

  Logger.Log(1, '--- Settings ---');
  Logger.Log(1, LogValue('--Settings->LogFileNum', IniEntries.LogFileNum.ToString, IniEntries.LogFileNumFromIni));
  Logger.Log(1, LogValue('--Settings->webClientVersion', IniEntries.WebClientVersion, IniEntries.WebClientVersionFromIni));

//  Logger.Log(1, '--- Database ---');
//  Logger.Log(1, LogValue('--Database->Server', IniEntries.DatabaseServer, IniEntries.DatabaseServerFromIni));
//  Logger.Log(1, LogValue('--Database->Database', IniEntries.DatabaseName, IniEntries.DatabaseNameFromIni));
//  Logger.Log(1, LogValue('--Database->Username', IniEntries.DatabaseUsername, IniEntries.DatabaseUsernameFromIni));
//  Logger.Log(1, LogValue('--Database->Password', IniEntries.DatabasePassword, IniEntries.DatabasePasswordFromIni));

  Logger.Log(1, '');
  Logger.Log(1, '--- URLs ---');
  try
    AuthServerModule := TAuthServerModule.Create(Self);
    AuthServerModule.StartAuthServer(ServerConfig.url, AUTH_MODEL);

    ApiServerModule := TApiServerModule.Create(Self);
    ApiServerModule.StartApiServer(ServerConfig.url, API_MODEL);

    AppServerModule := TAppServerModule.Create(Self);
    AppServerModule.StartAppServer(ServerConfig.url);

    WsServerModule := TWsServerModule.Create(Self);
    WsServerModule.StartWsServer(ServerConfig.url, WS_MODEL);
  except
    on E: Exception do
      Logger.Log(2, 'Failed to start server modules: ' + E.Message);
  end;
end;


end.

