#pragma once

#include "plainer.h"
#include "statistics.h"

#include <util/generic/hash.h>
#include <util/generic/hash_set.h>

namespace NPrivate {

    class TRicherReplicId : public TPlainer::IRicher {
    public:
        void Rich(NJson::TJsonValue& inserted) override;
    private:
        typedef THashSet<TString> TIntervals;
        typedef TVector<std::pair<ui32, TIntervals> > TReplicas;
        struct TService {
            THashMap <TString, TReplicas> ReplicasByDc;
            ui32 CurrentReplicId = 1;
        };
        THashMap<TString, TService> Services;
    };

    class TRicherControllerStatus : public TPlainer::IRicher {
    public:
        TRicherControllerStatus(bool reportFlagged);
        void Rich(NJson::TJsonValue& inserted) override;

    private:
        bool ReportFlagged = false;
    };

    class TRicherStatistics : public TPlainer::IRicher {
    public:
        TRicherStatistics(TVector<TStatisticsField::TPtr>& statistics, const TString& service);

        void Rich(NJson::TJsonValue& inserted) override;

    private:
        TVector<TStatisticsField::TPtr>& Statistics;
        const TString& Service;
    };

    class TRicherCheckConfigs : public TPlainer::IRicher {
    public:
        TRicherCheckConfigs(const NJson::TJsonValue& checkConfigResult);

        void Rich(NJson::TJsonValue& inserted) override;
    private:
        const NJson::TJsonValue& CheckConfigResult;
    };

    class TRicherReplicsConsistanse : public TPlainer::IRicher {
    public:
        virtual void Rich(NJson::TJsonValue& inserted) override;
        void UpdateFilter(TSet<TString>& filter);
        void InitializeByBroadcastResult(const NJson::TJsonValue& brcstResult);

    private:
        struct TInteravalData {
            TVector<ui64> InputValues;
            ui64 MinNormalValue = 0;
            ui64 MaxNormalValue = 0;
            bool Initialized = false;
        };

        typedef THashMap<TString, TInteravalData> TIntervals;

    private:
        static void InitializeIntervalData(TInteravalData& intervalData, const double minGoodRatio);
        static bool CheckBe(const NJson::TJsonValue& inserted, TString& interval);
        void BadBackend(NJson::TJsonValue& inserted, const char* status, const TInteravalData& intData, const TString& prefix="");
    private:
        TIntervals DocCountIntervals;
        TIntervals IndexSizeIntervals;
    };

    class TRicherFailDomainTagger : public TPlainer::IRicher {
        THashSet<TString> PerDCSearchServicesNames;
        TString TagPropName;
    public:
        TRicherFailDomainTagger(const THashSet<TString>& perDCSearchServicesNames, const TString& tagPropName);
        virtual void Rich(NJson::TJsonValue& inserted) override;
        void UpdateFilter(TSet<TString>& filter) const;
    };
}
