#pragma once

#include <saas/library/daemon_base/unistat_signals/signals.h>
#include <saas/rtyserver/model/realm/realm.h>

#include <kernel/search_daemon_iface/reqtypes.h>

#include <library/cpp/cgiparam/cgiparam.h>

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

class TSearchRequestData;

namespace NRTYServer {

    struct TUnistatRecordContext {
        TUnistatRecordContext(ERequestType type, ui64 duration, ui64 process, bool isSuccess)
            : RequestType(type)
            , DurationMs(duration)
            , ProcessMs(process)
            , IsSuccess(isSuccess)
        {
        };
        ERequestType RequestType = RT_Unknown;
        ui64 ReportByteSize = 0;
        ui64 DurationMs = 0;
        ui64 ProcessMs = 0;
        float CacheHit = 0;
        ui32 FastCacheHit = 0;
        ui32 TotalDocsCount = 0;
        ui32 ReportDocsCount = 0;
        ui32 CountUnanswered = 0;
        ui32 AnswerIsComplete = 1;
        bool IsSuccess = false;
        bool FailOnZero = false;
    };

    class TSearchSignals : public TSaasUnistatSignals {
    public:
        void Init(TUnistat &t) const;

    public:
        static void DoUnistatRecordContext(const TUnistatRecordContext &ctx);
    };
}

class TSaasRTYServerSignals : public NRTYServer::TSearchSignals {
public:
    static TVector<TString> RealmConfigNames;
    static THashMap<TString, ui32> LastMergeFinished;
    static bool SearchBanned;
    static bool AddTags;
public:
    struct TType {
        TString Name;
        TString SigOpt;
    };

    void Init(TUnistat& t) const;

    static void BuildSignals(TVector<TString> realmConfigNames, bool addTags=false);
    static void DoUnistatRequestData(const TCgiParameters& cgi);
    static bool DoUnistatRecordSearch(const NRTYServer::TUnistatRecordContext& ctx);
    static bool DoUnistatRecordIndex(ui16 code, ui64 duration);
    static void DoUnistatRecordDocDssm(bool anyDssmMismatch);
    static void DoUnistatRecordMissedDeltas();
    static void DoUnistatUserFactorCalcDefault();
    static void DoUnistatUserFactorCalcError();
    static void DoUnistatErrorSearch();
    static void DoUnistatUnavailable();
    static void DoUnistatTimeouted();

    static void UpdateSearchDisabledStatus(bool disabled);

    static void UpdateIndexState(ui32 value);
    static void UpdateIndexTimestamp(const TString& realmName, ui32 timestamp);
    static void UpdateAverageDocSize(ui32 value);
    static void UpdateOldDocCount(ui32 value);
    static void UpdateSurplusDocCount(ui32 value, TInstant maxDeadline);
    static void UpdateIndexDiskDocuments(ui32 value);
    static void UpdateIndexSearchableDocuments(ui32 value);

    static void OnMergerTaskFinish(const TString& realmConfigName, TDuration value);
    static void OnMergerTaskStart(const TString& realmConfigName);
    static void OnMergerTaskFailed(const TString& realmConfigName);
    static void OnCannotMerge(const TString& realmConfigName, int extraSegments);

    static void DoUnistatNoBertEmbedding();

private:
    void InitSearchSignalsGroup(TUnistat& t, bool isService, TString cache, const TVector<double>& intervals) const;

    static void PushCountSignals(TUnistat& inst, const TString& countSign, const TString& cacheSign);

    static TString ConvertRealmToString(const TString& realmConfigName);
};
