#pragma once

#include <balancer/kernel/http/parser/client_proto.h>

#include <util/generic/string.h>
#include <util/generic/maybe.h>
#include <util/generic/vector.h>
#include <util/datetime/base.h>

namespace NSrvKernel {

    struct TSslEarlyDataParams {
        bool Enabled = false;
        ui32 MaxEarlyData = 16384;
        ui32 RecvMaxEarlyData = 16384;
    };

    struct TSslClientCertData {
        TMaybe<TString> CN;
        TMaybe<TString> Subject;
        TMaybe<TString> SerialNumber;
        TMaybe<long> VerifyResult;
    };

    /**
     * Container with Ja3 information.
     *
     * To prevent copy vectors from TSslIO to TSslProps we use this class
     * as a container for storing constant references.
     */
    struct TSslJa3Data {
        TSslJa3Data(ui32 version, const TVector<ui8>& ciphers, const TVector<int>& clientExtensions,
            const TVector<ui8>& ellipticCurves, const TVector<ui8>& ellipticCurvesPointFormats,
            const TVector<ui8>& signatureAlgorithms, const TVector<ui8>& signatureAlgorithmsCert,
            const TVector<ui8>& supportedVersions, const TVector<ui8>& applicationLayerProtocolNegotiation,
            const TVector<ui8>& keyShare, const TVector<ui8>& pskKeyExchangeModes)
        : LegacyVersion(version)
        , Ciphers(ciphers)
        , ClientExtensions(clientExtensions)
        , EllipticCurves(ellipticCurves)
        , EllipticCurvesPointFormats(ellipticCurvesPointFormats)
        , SignatureAlgorithms(signatureAlgorithms)
        , SignatureAlgorithmsCert(signatureAlgorithmsCert)
        , SupportedVersions(supportedVersions)
        , ApplicationLayerProtocolNegotiation(applicationLayerProtocolNegotiation)
        , KeyShare(keyShare)
        , PskKeyExchangeModes(pskKeyExchangeModes)
        {}

        ui32 LegacyVersion = 0;
        const TVector<ui8>& Ciphers;
        const TVector<int>& ClientExtensions;
        const TVector<ui8>& EllipticCurves;
        const TVector<ui8>& EllipticCurvesPointFormats;
        const TVector<ui8>& SignatureAlgorithms;
        const TVector<ui8>& SignatureAlgorithmsCert;
        const TVector<ui8>& SupportedVersions;
        const TVector<ui8>& ApplicationLayerProtocolNegotiation;
        const TVector<ui8>& KeyShare;
        const TVector<ui8>& PskKeyExchangeModes;
    };

    struct TSslProps {
        TInstant HandshakeCompleted;
        TDuration HandshakeDuration;
        TSslClientCertData* ClientCertData = nullptr;
        TSslJa3Data* Ja3Data = nullptr;

        EClientProto NextProto = EClientProto::CP_HTTP;

        bool ThisConnIsSsl = false;
        bool HandshakeUsedTlsTickets = false;
        ui16 CurrentCipherId = 0;
        ui16 CurrentProtocolId = 0;

        bool EarlyData = false;

        TString TicketName;
        TString TicketIV;
    };
}
