#pragma once

#include <balancer/kernel/stats/manager.h>
#include <balancer/kernel/helpers/default_instance.h>
#include <balancer/kernel/helpers/hash.h>
#include <balancer/kernel/ssl/protocol_version.h_serialized.h>
#include <library/cpp/containers/flat_hash/flat_hash.h>
#include <openssl/err.h>

#include "ssl_errors.h"

namespace NSsl {

    class TSslErrorStats : public NSrvKernel::TWithMutableInstance<TSslErrorStats> {
    public:
        void AddActiveError(const TString& errorName) {
            ActiveErrors_.insert(errorName);
        }

        NSrvKernel::TSharedCounter* GetCounter(int errorCode, NSrvKernel::TSharedStatsManager& statsManager, size_t id);

        const THashSet<TString>& ActiveErrors() {
            return ActiveErrors_;
        }

    private:
        THashSet<TString> ActiveErrors_ = NSrvKernel::DefaultSslErrors;

        THashMap<int, THolder<NSrvKernel::TSharedCounter>> Counters_;
    };

    class TStats {
    public:
        TStats(NSrvKernel::TSharedCounter emptyRequests, NSrvKernel::TSharedCounter httpsRequests,
            NSrvKernel::TSharedCounter httpRequests, NSrvKernel::TSharedCounter droppedExperiments,
            NSrvKernel::TSharedCounter errorsTotal, NSrvKernel::TSharedCounter zeroErrors,
            NFH::TFlatHashMap<EProtocolVersion, THolder<NSrvKernel::TSharedCounter>>& protocolVersions,
            NSrvKernel::TSharedStatsManager& statsManager, size_t workerId) noexcept;

        void RegisterError(int errorCode);

    public:
        NFH::TFlatHashMap<int, size_t, NSrvKernel::TNumericHash<int>> Errors;
        NFH::TFlatHashMap<EProtocolVersion, THolder<NSrvKernel::TSharedCounter>> ProtocolVersions;

        NSrvKernel::TSharedCounter EmptyRequests;
        NSrvKernel::TSharedCounter HttpsRequests;
        NSrvKernel::TSharedCounter HttpRequests;
        NSrvKernel::TSharedCounter DroppedExperiments;
        NSrvKernel::TSharedCounter ErrorsTotal;
        NSrvKernel::TSharedCounter ZeroErrors;
    private:
        size_t Id_ = 0;
        NSrvKernel::TSharedStatsManager& StatsManager_;
    };
}
