unit Main;
//Authors:
//Elias Sarraf
//Mac Stephens
//Cameron Hayes
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, Lookup.Service, Api.Server.Module, App.Server.Module,
  ExeInfo;

type
  TFMain = class(TForm)
    memoInfo: TMemo;
    btnApiSwaggerUI: TButton;
    btnData: TButton;
    btnExit: TButton;
    initTimer: TTimer;
    btnAuthSwaggerUI: TButton;
    ExeInfo1: TExeInfo;
    btnQB: TButton;
    procedure btnApiSwaggerUIClick(Sender: TObject);
    procedure btnDataClick(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);
    procedure btnQBClick(Sender: TObject);

  strict private
    procedure StartServers;
    procedure UpdateGUI;
  end;

var
  FMain: TFMain;

implementation

uses
  Common.Logging,
  Common.Config,
  Sparkle.Utils,
  Api.Database,
  Data, qbAPI;

{$R *.dfm}

{ TMainForm }

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.btnDataClick(Sender: TObject);
begin
  FData := TFData.Create( self );
  FData.ShowModal;
  FData.Free;
end;

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

procedure TFMain.btnQBClick(Sender: TObject);
begin
  FQB := TfQB.Create( self );
  FQB.ShowModal;
  FQB.Free;
end;

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

procedure TFMain.btnApiSwaggerUIClick(Sender: TObject);
begin
  ShellExecute(Handle, 'open', PChar(TSparkleUtils.CombineUrlFast(ApiServerModule.XDataServer.BaseUrl, 'swaggerui')), nil, nil, SW_SHOWNORMAL);
end;

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

procedure TFMain.StartServers;
// Reads from the ini file to figure out what IP the database is located at and
// whether or not Twilio automatic updates should be enabled
var
  iniFile: TIniFile;
  iniStr: string;
begin
  // The version is centered when the app is running
  Logger.Log( 1, '*******************************************************' );
  Logger.Log( 1, '*                  kgOrdersServer                     *' );
  Logger.Log(1, Format('                  Version: %s               ', [FMain.ExeInfo1.FileVersion]));
  Logger.Log( 1, '*            Developed by EM Systems, Inc.            *' );
  Logger.Log( 1, '*******************************************************' );
  Logger.Log( 1, '' );

  iniFile := TIniFile.Create( ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini' );
  try
    Logger.Log( 1, 'iniFile: ' + ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini' );

    Logger.Log( 1, 'LogLevels are displayed here.  They were set in kgOrdersServer.dpr, it executes first' );
    Logger.Log(1, '--- Settings ---');
    iniStr := iniFile.ReadString( 'Settings', 'MemoLogLevel', '' );
    if iniStr.IsEmpty then
      Logger.Log( 1, '--Settings->memoLogLevel: Entry not found - default: 3' )
    else
      Logger.Log( 1, '--Settings->memoLogLevel: ' + iniStr );

    iniStr := iniFile.ReadString( 'Settings', 'FileLogLevel', '' );
    if iniStr.IsEmpty then
      Logger.Log( 1, '--Settings->fileLogLevel: Entry not found - default: 4' )
    else
      Logger.Log( 1, '--Settings->fileLogLevel: ' + iniStr );

    Logger.Log( 1, '' );
    iniStr := iniFile.ReadString( 'Settings', 'LogFileNum', '' );
    if iniStr.IsEmpty then
      Logger.Log( 1, '--Settings->LogFileNum: Entry not found' )
    else
      Logger.Log( 1, '--Settings->LogFileNum: ' + IntToStr(StrToInt(iniStr) - 1) );

    Logger.Log(1, '--- Database ---');
    iniStr := IniFile.ReadString( 'Database', 'Server', '' );
    if iniStr.IsEmpty then
      Logger.Log( 1, '----Database->Server: Entry not found - ERROR: ini entry required!!!' )
    else
      Logger.Log( 1, '----Database->Server: ' + iniStr );

    iniStr := iniFile.ReadString('Database', 'Database', '');
    if iniStr.IsEmpty then
      Logger.Log( 1, '----Database->Database: ini entry not found - default: kg_order_entry' )
    else
      Logger.Log( 1, '----Database->Database: ini entry: ' + iniStr );

    iniStr := iniFile.ReadString('Database', 'Username', '');
    if iniStr.IsEmpty then
      Logger.Log( 1, '----Database->Username: Entry not found - default: root' )
    else
      Logger.Log( 1, '----Database->Username: ' + iniStr );

    iniStr := iniFile.ReadString('Database', 'Password', '');
    if iniStr.IsEmpty then
      Logger.Log( 1, '----Database->Password: Entry not found - default: xxxxxx' )
    else
      Logger.Log( 1, '----Database->Password: xxxxxxxx' );

    Logger.Log(1, '---Quickbooks---');
    iniStr := IniFile.ReadString( 'Quickbooks', 'Enabled', '' );
    if iniStr.IsEmpty then
      Logger.Log( 1, '--Quickbooks->Enabled: Entry not found - default: yes' )
    else
      Logger.Log( 1, '--Quickbooks->Enabled: ' + iniStr );

    iniStr := IniFile.ReadString( 'Quickbooks', 'CompanyID', '' );
    if iniStr.IsEmpty then
      Logger.Log( 1, '--Quickbooks->CompanyID: Entry not found' )
    else
      Logger.Log( 1, '--Quickbooks->CompanyID: Entry found' );

    iniStr := IniFile.ReadString( 'Quickbooks', 'ClientID', '' );
    if iniStr.IsEmpty then
      Logger.Log( 1, '--Quickbooks->ClientID: Entry not found' )
    else
      Logger.Log( 1, '--Quickbooks->ClientID: Entry found' );

    iniStr := IniFile.ReadString( 'Quickbooks', 'ClientSecret', '' );
    if iniStr.IsEmpty then
      Logger.Log( 1, '--Quickbooks->ClientSecret: Entry not found' )
    else
      Logger.Log( 1, '--Quickbooks->ClientSecret: Entry found' );

    iniStr := IniFile.ReadString( 'Quickbooks', 'RefreshToken', '' );
    if iniStr.IsEmpty then
      Logger.Log( 1, '--Quickbooks->RefreshToken: Entry not found' )
    else
      Logger.Log( 1, '--Quickbooks->RefreshToken: Entry found' );

    iniStr := IniFile.ReadString( 'Quickbooks', 'AccessToken', '' );
    if iniStr.IsEmpty then
      Logger.Log( 1, '--Quickbooks->AccessToken: Entry not found' )
    else
      Logger.Log( 1, '--Quickbooks->AccessToken: Entry found' );

    iniStr := IniFile.ReadString( 'Quickbooks', 'LastRefresh', '' );
    if iniStr.IsEmpty then
      Logger.Log( 1, '--Quickbooks->LastRefresh: Entry not found' )
    else
      Logger.Log( 1, '--Quickbooks->LastRefresh: Entry Found' );

    Logger.Log( 1, '' );
  finally
    IniFile.Free;
  end;

  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 );

  UpdateGUI;
end;

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

procedure TFMain.UpdateGUI;
begin
  if AuthServerModule.SparkleHttpSysDispatcher.Active then
    memoInfo.Lines.Add( 'AuthServer started at: ' + AuthServerModule.XDataServer.BaseUrl )
  else
    memoInfo.Lines.Add( 'AuthServer stopped' );

  if ApiServerModule.SparkleHttpSysDispatcher.Active then
    memoInfo.Lines.Add( 'ApiServer started at: ' + ApiServerModule.XDataServer.BaseUrl )
  else
    memoInfo.Lines.Add( 'ApiServer stopped' );
end;

end.
