#ifndef OverbyteIcsIpStmLogTst1H
#define OverbyteIcsIpStmLogTst1H

#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
#include <Vcl.ComCtrls.hpp>
#include <Vcl.Buttons.hpp>
#include <Vcl.Dialogs.hpp>

#include "OverbyteIcsIniFiles.hpp"
#include "OverbyteIcsWSocket.hpp"
#include "OverbyteIcsWSocketS.hpp"
#include "OverbyteIcsSslSessionCache.hpp"
#include "OverbyteIcsUtils.hpp"
#include "OverbyteIcsStreams.hpp"
#include "OverbyteIcsIpStreamLog.hpp"
#include "OverbyteIcsSslX509Certs.hpp"
#include "OverbyteIcsWndControl.hpp"
#include "OverbyteIcsTicks64.hpp"
#include "OverbyteIcsTypes.hpp"
#include "OverbyteIcsSslBase.hpp"
#include "OverbyteIcsSslUtils.hpp"
#include "OverbyteIcsAppMonCli.hpp"

#include <memory>
#include <set>

class TIpLogForm : public TForm
{
__published:
    TPageControl *PageControl1;
    TTabSheet *SheetOperation;
    TPanel *PanelBottom;
    TLabel *LabelSendClient;
    TLabel *LabelSendServer;
    TButton *doStop;
    TButton *doLocal;
    TButton *doClient;
    TButton *doExit;
    TButton *doServer;
    TButton *doClear;
    TButton *doCliSendFile;
    TEdit *SendFileName;
    TBitBtn *SelectFile;
    TButton *doSrvSendFile;
    TPanel *PanelSplitter;
    TMemo *LogWin;
    TMemo *DataWin;
    TTabSheet *SheetSettings;
    TGroupBox *BoxClient;
    TLabel *Label5;
    TLabel *Label2;
    TLabel *Label23;
    TLabel *Label27;
    TMemo *RemoteHosts;
    TComboBox *RemotePort;
    TRadioGroup *VerifyCertMode;
    TCheckBox *RevokeCheck;
    TCheckBox *PingRemote;
    TCheckBox *ReportChain;
    TComboBox *SslCliSec;
    TEdit *CliRetryAttempts;
    TGroupBox *BoxServer;
    TLabel *Label6;
    TLabel *Label7;
    TLabel *Label11;
    TLabel *Label10;
    TLabel *Label14;
    TLabel *Label15;
    TLabel *Label16;
    TLabel *Label8;
    TLabel *Label12;
    TLabel *Label13;
    TLabel *Label17;
    TLabel *Label18;
    TLabel *Label20;
    TLabel *Label21;
    TLabel *Label22;
    TLabel *Label31;
    TLabel *Label24;
    TLabel *Label26;
    TComboBox *ServerPort;
    TEdit *MaxSockets;
    TEdit *SslServCert;
    TEdit *SslCertKey;
    TEdit *SslCACerts;
    TEdit *SslCertPassword;
    TEdit *SrvTimeout;
    TEdit *SslDomainName;
    TCheckBox *SslCertAutoOrder;
    TEdit *SslCertExpireDays;
    TComboBox *SslCertSupplierProto;
    TComboBox *SslCertChallenge;
    TComboBox *SslCertPKeyType;
    TEdit *SslCertDirWork;
    TComboBox *SslCertSignDigest;
    TEdit *SslCertProduct;
    TEdit *ProxyURL;
    TComboBox *SslSrvSec;
    TComboBox *DnsChlgType;
    TGroupBox *BoxLocalAddr;
    TLabel *Label9;
    TLabel *Label19;
    TLabel *Label4;
    TLabel *Label25;
    TRadioGroup *Protocol;
    TComboBox *LocalAddr;
    TCheckBox *UseSSL;
    TEdit *SslCertAuth;
    TEdit *LocalPort;
    TRadioGroup *SocketFamily;
    TEdit *DirLogs;
    TBitBtn *SelDirLogs;
    TCheckBox *UseUtf8;
    TGroupBox *BoxSampleData;
    TLabel *Label3;
    TCheckBox *DataServer;
    TCheckBox *DataClient;
    TCheckBox *HeavyTraffic;
    TCheckBox *RawData;
    TEdit *DataGap;
    TCheckBox *DataUnicode;
    TTimer *DataTimer;
    TOpenDialog *OpenDialog;
    TSslX509Certs *SslX509Certs;
    TSslAvlSessionCache *SslAvlSessionCache;
    TTimer *TimerLog;
    TIcsAppMonCli *IcsAppMonCli;
    void __fastcall FormCreate(TObject *Sender);
    void __fastcall doExitClick(TObject *Sender);
    void __fastcall DataTimerTimer(TObject *Sender);
    void __fastcall doLocalClick(TObject *Sender);
    void __fastcall doClientClick(TObject *Sender);
    void __fastcall doServerClick(TObject *Sender);
    void __fastcall doStopClick(TObject *Sender);
    void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
    void __fastcall LocalAddrChange(TObject *Sender);
    void __fastcall SocketFamilyChange(TObject *Sender);
    void __fastcall doClearClick(TObject *Sender);
    void __fastcall doCliSendFileClick(TObject *Sender);
    void __fastcall SelectFileClick(TObject *Sender);
    void __fastcall doSrvSendFileClick(TObject *Sender);
    void __fastcall FormResize(TObject *Sender);
    void __fastcall SslX509CertsCertProg(TObject *Sender, TLogOption LogOption, const String Msg);
    void __fastcall SslX509CertsNewCert(TObject *Sender);
    void __fastcall SslX509CertsChallengeDNS(TObject *Sender, const TChallengeItem &ChallengeItem, bool &ChlgOK);
    void __fastcall SslX509CertsOAuthAuthUrl(TObject *Sender, const String URL);
    void __fastcall SelDirLogsClick(TObject *Sender);
    void __fastcall TimerLogTimer(TObject *Sender);
    void __fastcall IcsAppMonCliLogEvent(TObject *Sender, const String Line);

private:
    std::unique_ptr<TIcsIpStrmLog> FIpLogClient;
    std::unique_ptr<TIcsIpStrmLog> FIpLogServer;
    struct TFileSend {
        std::unique_ptr<TFileStream> Stream;
        std::set<int> Channels;
        bool Starting = false;
    };
    TFileSend FCliSend;
    TFileSend FSrvSend;
    std::unique_ptr<TIcsBuffLogStream> FIcsBuffLogStream;
    String FIniFileName;
    String FBuffLogLines;
    int FCSerialNr = 1;
    int FSSerialNr = 1;
    __int64 FCertCheckTrigger = 0;

    void AddLog(const String &S);
    void OpenLogFile();
    void SetButtons(bool Started);
    void StartAppMon();
    bool SetupTcpServerHost(const String &Port, const String &HostTag);
    void SendFile(TIcsIpStrmLog *Sender, TFileSend &Send, const String &Who);
    void FileSendStateChange(TFileSend &Send, int Socnr, TStrmLogState LogState);
    void ReleaseFileSend(TFileSend &Send);
    void __fastcall IpLogClientRecvEvent(TObject *Sender, int Socnr, const String Line);
    void __fastcall IpLogClientProgEvent(TObject *Sender, int Socnr, TLogOption LogOption, const String Msg);
    void __fastcall IpLogClientChangeEvent(TObject *Sender, int Socnr, TStrmLogState LogState);
    void __fastcall IpLogClientSslCertVerifyEvent(TObject *Sender, TX509List *CertChain, int &VerifyCode,
                                                  String &VerifyInfo, bool &Disconnect);
    void __fastcall IpLogServerRecvEvent(TObject *Sender, int Socnr, const String Line);
    void __fastcall IpLogServerProgEvent(TObject *Sender, int Socnr, TLogOption LogOption, const String Msg);
    void __fastcall IpLogServerChangeEvent(TObject *Sender, int Socnr, TStrmLogState LogState);

public:
    __fastcall TIpLogForm(TComponent *Owner);
    __fastcall ~TIpLogForm();
};

extern PACKAGE TIpLogForm *IpLogForm;

#endif
