#pragma once
#include <library/cpp/unistat/unistat.h>
#include <saas/library/daemon_base/unistat_signals/signals.h>

#include <util/generic/map.h>

class TProxyServicesConfig;

class TSaasIndexerProxySignals : public TSaasProxyUnistatSignals {
public:
    struct TUnistatRecordContext {
        TUnistatRecordContext(const TString& service, int code, ui64 duration, ui64 age, bool isFromMeta, bool isDeferred,
                          const TString& source, bool isDuplicated, TVector<TString>&& distrAttrs)
            : Service(service)
            , Code(code)
            , DurationMs(duration)
            , AgeSec(age)
            , IsFromMeta(isFromMeta)
            , IsDeferred(isDeferred)
            , Source(source)
            , IsDuplicated(isDuplicated)
            , DistrAttrs(distrAttrs)
        {};
        TString Service;
        int Code;
        ui64 DurationMs;
        ui64 AgeSec;
        bool IsFromMeta;
        bool IsDeferred;
        TString Source;
        bool IsDuplicated;
        TVector<TString> DistrAttrs;
    };


    TSaasIndexerProxySignals();

    void Init(TUnistat& t) const;
    virtual void AddDistrAttr(const TString& distrAttr);

    static void BuildSignals(const TSet<TString>& services, const TProxyServicesConfig& config);

    static bool DoUnistatRecord(const TUnistatRecordContext&);

private:
    TSet<TString> DistrAttrs; //configuration data

    static TSet<TString> TrackedDistrAttrs; //saved configuration data

private:
    static void DrillForSources(TUnistat& t, const TString& signalBeg, const TString& signalEnd,
        NUnistat::TPriority prio, const TVector<double>& intervals = TVector<double>(), bool visible=false);
};


class TPersqueueServiceSignals : public TSaasUnistatSignals {
public:
    TPersqueueServiceSignals(const TString& service, const TVector<TString>& shards);
    void Processed(bool written, TStringBuf shard, ui64 process_time);
    void UpdateInFlight(TStringBuf shard, TAtomicCounter& inFlight);

public:
    void Init(TUnistat& t) const override;

private:
    TString GetSignalSuffix(TStringBuf shard, const TStringBuf name) const;

private:
    const TString Service;
    const TVector<TString> Shards;
};
