#ifndef OverbyteIcsSslWebServ1H
#define OverbyteIcsSslWebServ1H

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

#include "OverbyteIcsTypes.hpp"
#include "OverbyteIcsSslBase.hpp"
#include "OverbyteIcsWndControl.hpp"
#include "OverbyteIcsWSocket.hpp"
#include "OverbyteIcsWSocketS.hpp"
#include "OverbyteIcsHttpSrv.hpp"
#include "OverbyteIcsSslSessionCache.hpp"

#include <memory>

class TMyHttpConnection : public THttpConnection
{
    typedef THttpConnection inherited;
public:
    AnsiString PostedRawData;
    String PostedDataBuffer;
    int DataLen = 0;
    unsigned LastHandshake = 0;
    using THttpConnection::Answer404;
    __fastcall virtual TMyHttpConnection(TComponent *AOwner) : THttpConnection(AOwner) {}
};

class TSslWebServForm : public TForm
{
__published:
    TPanel *ToolsPanel;
    TMemo *DisplayMemo;
    TLabel *Label1;
    TEdit *DocDirEdit;
    TLabel *Label2;
    TEdit *DefaultDocEdit;
    TButton *StartHttpsButton;
    TButton *StopButton;
    TLabel *Label3;
    TEdit *PortHttpsEdit;
    TLabel *ClientHttpsCountLabel;
    TLabel *Label5;
    TButton *ClearButton;
    TCheckBox *DisplayHeaderCheckBox;
    TCheckBox *WriteLogFileCheckBox;
    TLabel *Label4;
    TEdit *CertFileEdit;
    TLabel *Label6;
    TEdit *PrivKeyFileEdit;
    TLabel *Label7;
    TEdit *PassPhraseEdit;
    TLabel *Label8;
    TLabel *Label9;
    TEdit *AcceptableHostsEdit;
    TLabel *Label10;
    TEdit *CAPathEdit;
    TLabel *Label11;
    TEdit *CAFileEdit;
    TCheckBox *VerifyPeerCheckBox;
    TSslHttpServer *SslHttpServer1;
    TSslContext *SslContext1;
    THttpServer *HttpServer2;
    TButton *StartHttpButton;
    TEdit *PortHttpEdit;
    TLabel *Label12;
    TLabel *Label15;
    TLabel *ClientHttpCountLabel;
    TCheckBox *DisplaySslInfoCheckBox;
    TSslAvlSessionCache *SslAvlSessionCache1;
    TLabel *Label21;
    TEdit *SslCipherEdit;
    TLabel *Label14;
    TComboBox *SslCipherList;
    TLabel *Label22;
    TComboBox *ListenAddr;
    TLabel *Label20;
    TComboBox *SslMinVersion;
    TLabel *Label23;
    TComboBox *SslMaxVersion;
    TCheckBox *OldSslCheckBox;
    TCheckBox *WebDAVCheckBox;
    TComboBox *SslSecLevel;
    TLabel *Label25;
    TEdit *WellKnownPathEdit;
    TLabel *Label26;
    TEdit *SslCipher13Edit;
    TLabel *Label13;
    TLabel *Label19;
    TEdit *SslCryptoGroups;
    void __fastcall FormShow(TObject *Sender);
    void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
    void __fastcall FormCreate(TObject *Sender);
    void __fastcall SslHttpServer1GetDocument(TObject *Sender, TObject *Client, THttpGetFlag &Flags);
    void __fastcall StartHttpsButtonClick(TObject *Sender);
    void __fastcall StopButtonClick(TObject *Sender);
    void __fastcall SslHttpServer1ClientConnect(TObject *Sender, TObject *Client, System::Word Error);
    void __fastcall SslHttpServer1ClientDisconnect(TObject *Sender, TObject *Client, System::Word Error);
    void __fastcall SslHttpServer1ServerStarted(TObject *Sender);
    void __fastcall SslHttpServer1ServerStopped(TObject *Sender);
    void __fastcall SslHttpServer1HeadDocument(TObject *Sender, TObject *Client, THttpGetFlag &Flags);
    void __fastcall SslHttpServer1PostedData(TObject *Sender, TObject *Client, System::Word Error);
    void __fastcall SslHttpServer1PostDocument(TObject *Sender, TObject *Client, THttpGetFlag &Flags);
    void __fastcall ClearButtonClick(TObject *Sender);
    void __fastcall WriteLogFileCheckBoxClick(TObject *Sender);
    void __fastcall SslHttpServer1SslVerifyPeer(TObject *Sender, int &Ok, TX509Base *Cert);
    void __fastcall SslHttpServer1SslSvrGetSession(TObject *Sender, void *&SslSession, void *SessId, int Idlen, bool &IncRefCount);
    void __fastcall SslHttpServer1SslSvrNewSession(TObject *Sender, void *SslSession, void *SessId, int Idlen, bool &AddToInternalCache);
    void __fastcall StartHttpButtonClick(TObject *Sender);
    void __fastcall HttpServer2ServerStopped(TObject *Sender);
    void __fastcall HttpServer2ServerStarted(TObject *Sender);
    void __fastcall HttpServer2ClientConnect(TObject *Sender, TObject *Client, System::Word Error);
    void __fastcall HttpServer2ClientDisconnect(TObject *Sender, TObject *Client, System::Word Error);
    void __fastcall SslHttpServer1BeforeProcessRequest(TObject *Sender, TObject *Client);
    void __fastcall SslHttpServer1SslHandshakeDone(TObject *Sender, System::Word ErrCode, TX509Base *PeerCert, bool &Disconnect);
    void __fastcall SslHttpServer1SslServerName(TObject *Sender, TSslContext *&Ctx, TTlsExtError &ErrCode);
    void __fastcall SslHttpServer1WellKnownDir(TObject *Sender, TObject *Client, const String Path, String &BodyStr);
    void __fastcall HttpServer2WellKnownDir(TObject *Sender, TObject *Client, const String Path, String &BodyStr);
    void __fastcall SslHttpServer1SslAlpnSelect(TObject *Sender, TStrings *ProtoList, String &SelProto, TTlsExtError &ErrCode);
    void __fastcall SslHttpServer1Display(TObject *Sender, const String Msg);
    void __fastcall SslHttpServer1WebDAVDocument(TObject *Sender, TObject *Client, THttpMethod HttpMethod, THttpGetFlag &Flags);
public:
    void Display(const String &Msg);
    __fastcall TSslWebServForm(TComponent *Owner);
    __fastcall virtual ~TSslWebServForm();
private:
    String FIniFileName;
    bool FInitialized = false;
    int FCountRequests = 0;
    std::unique_ptr<TStreamWriter> FLogFile;
    String FLogFileName;
    unsigned FRenegotiationInterval = 0;
    String FSrvSslCert;
    String FSrvCipherList;
    String FCliCipherList;
    String FSrvGroupList;
    void CreateVirtualDocument_Demo(TMyHttpConnection *Client, THttpGetFlag &Flags);
    void CreateVirtualDocument_time_htm(TMyHttpConnection *Client, THttpGetFlag &Flags);
    void CreateVirtualDocument_redir_htm(TMyHttpConnection *Client, THttpGetFlag &Flags);
    void SendHtmlStream(TMyHttpConnection *Client, const String &Status, const String &ExtraHeader, const String &Body);
    void __fastcall BackgroundException(TObject *Sender, Exception *E, bool &CanClose);
    void ProcessPostedData_CgiFrm1(TMyHttpConnection *Client);
    void SetWebDAVOptions(THttpServer *Server);
    void CloseLogFile();
    void OpenLogFile();
};

extern PACKAGE TSslWebServForm *SslWebServForm;

#endif
