#pragma once

#include "hpack_definitions.h"
#include "hpack_table.h"

#include <util/generic/noncopyable.h>

namespace NSrvKernel::NHTTP2 {

    // Estimates the minimum size an unpacked header list will take given the header block size.
    [[nodiscard]] size_t GetMinHeaderListSize(size_t headerBlockSize) noexcept;


    // THPackBase ======================================================================================================

    class THPackBase : public TMoveOnly {
    public:
        void DumpDynamicTable(size_t& sz, THeadersList& headers) noexcept;

    private:
        virtual THPackTableBase& GetTable() noexcept = 0;
    };


    // THPackDecoder ===================================================================================================

    class THPackDecoder : public THPackBase {
    public:
        explicit THPackDecoder(const THPackDecoderSettings& settings) noexcept;

        TErrorOr<THeadersList> Decode(TStringBuf) noexcept;

        void UpdateSettings(const THPackDecoderSettings& settings);

    private:
        THPackTableBase& GetTable() noexcept override;

    private:
        THPackDecoderSettings Settings_;
        THPackDecoderTable Table_;
    };


    // THPackEncoder ===================================================================================================

    class THPackEncoder : public THPackBase {
    public:
        explicit THPackEncoder(const THPackEncoderSettings& settings) noexcept;

        TChunkList Encode(const THeadersList&) noexcept;

        void UpdateSettings(const THPackEncoderSettings& settings);

        void UpdateHeaderTableSize(ui32 newSize);

    private:
        THPackTableBase& GetTable() noexcept override;

    private:
        THPackEncoderSettings Settings_;
        THPackEncoderTable Table_;
        TMaybe<ui32> MinimalSizeUpdate_;
        TMaybe<ui32> PendingSizeUpdate_;
    };
}
