#include "stats.h"

#include <balancer/modules/cookie_policy/common/enums.h_serialized.h>
#include <balancer/kernel/cookie/gdpr/common/gdpr.h_serialized.h>


namespace NModCookiePolicy {

    TSharedCounter MakeCounter(TVector<TString> id, TSharedStatsManager& manager) {
        id.insert(id.begin(), "cpol");
        return manager.MakeCounter(JoinNonemptySeq(id)).AllowDuplicate().Build();
    }

    TGlobalStats::TGlobalStats(TString uuid, TSharedStatsManager& manager)
        : Total(MakeCounter({uuid, "total"}, manager))
        , Off(MakeCounter({uuid, "off"}, manager))
        , Checked(MakeCounter({uuid, "checked"}, manager))
        , ModifiedReq(MakeCounter({uuid, "modified-req"}, manager))
        , ModifiedResp(MakeCounter({uuid, "modified-resp"}, manager))
        , ParserTotal(MakeCounter({uuid, "parser-total"}, manager))
        , ParserSkip(MakeCounter({uuid, "parser-skip"}, manager))
        , ParserPass(MakeCounter({uuid, "parser-pass"}, manager))
        , ParserFail(MakeCounter({uuid, "parser-fail"}, manager))
        , ParserFix(MakeCounter({uuid, "parser-fix"}, manager))
        , ParserFixDryRun(MakeCounter({uuid, "parser-fix-dryRun"}, manager))
        , ParserCookieTotal(MakeCounter({uuid, "parser-cookie-total"}, manager))
        , ParserCookiePass(MakeCounter({uuid, "parser-cookie-pass"}, manager))
        , ParserCookieFail(MakeCounter({uuid, "parser-cookie-fail"}, manager))
        , ParserCookieDrop(MakeCounter({uuid, "parser-cookie-drop"}, manager))
        , ParserCookieDropDryRun(MakeCounter({uuid, "parser-cookie-drop-dryRun"}, manager))
        , GdprCookie(MakeCounter({uuid, "Gdpr-cookie"}, manager))
        , GdprConflict(MakeCounter({uuid, "Gdpr-conflict"}, manager))
        , GdprBadValue(MakeCounter({uuid, "Gdpr-badValue"}, manager))
        , GdprPopup(MakeCounter({uuid, "GdprPopup-cookie"}, manager))
        , GdprPopupNoGdpr(MakeCounter({uuid, "GdprPopup-noGdpr"}, manager))
        , IsGdprCookie(MakeCounter({uuid, "IsGdpr-cookie"}, manager))
        , IsGdprDuplicate(MakeCounter({uuid, "IsGdpr-duplicate"}, manager))
        , IsGdprBadValue(MakeCounter({uuid, "IsGdpr-badValue"}, manager))
        , IsGdprBCookie(MakeCounter({uuid, "IsGdprB-cookie"}, manager))
        , IsGdprBFiltered(MakeCounter({uuid, "IsGdprB-filtered"}, manager))
        , IsGdprBDuplicate(MakeCounter({uuid, "IsGdprB-duplicate"}, manager))
        , IsGdprBBadValue(MakeCounter({uuid, "IsGdprB-badValue"}, manager))
        , IsGdprBOff(MakeCounter({uuid, "IsGdprB-off"}, manager))
        , XYandexEURequest(MakeCounter({uuid, "XYandexEURequest"}, manager))
        , XYandexEURequestOff(MakeCounter({uuid, "XYandexEURequest-off"}, manager))
        , XIpProperties(MakeCounter({uuid, "XIpProperties"}, manager))
        , XIpPropertiesOff(MakeCounter({uuid, "XIpProperties-off"}, manager))
        , GdprDomain(MakeCounter({uuid, "gdpr-domain"}, manager))
        , ParserErrors_(JoinNonemptySeq({uuid, "parser-err"}), manager)
        , GdprGeo_(JoinNonemptySeq({uuid, "gdpr-geo"}), manager)
        , GdprMod_(JoinNonemptySeq({uuid, "gdpr-mod"}), manager)
        , GdprSrc_(JoinNonemptySeq({uuid, "gdpr-src"}), manager)
        , GdprSafeGeo_(JoinNonemptySeq({uuid, "gdpr-safe-geo"}), manager)
        , GdprSafeMod_(JoinNonemptySeq({uuid, "gdpr-safe-mod"}), manager)
        , GdprSafeSrc_(JoinNonemptySeq({uuid, "gdpr-safe-src"}), manager)
    {}

    TGlobalStats::TGlobalStats(const TGlobalStats& tmpl, ui32 workerId)
        : Y_BALANCER_INIT_WORKER_COUNTER(Total, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(Off, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(Checked, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ModifiedReq, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ModifiedResp, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ParserTotal, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ParserSkip, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ParserPass, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ParserFail, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ParserFix, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ParserFixDryRun, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ParserCookieTotal, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ParserCookiePass, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ParserCookieFail, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ParserCookieDrop, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ParserCookieDropDryRun, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(GdprCookie, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(GdprConflict, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(GdprBadValue, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(GdprPopup, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(GdprPopupNoGdpr, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(IsGdprCookie, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(IsGdprDuplicate, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(IsGdprBadValue, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(IsGdprBCookie, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(IsGdprBFiltered, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(IsGdprBDuplicate, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(IsGdprBBadValue, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(IsGdprBOff, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(XYandexEURequest, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(XYandexEURequestOff, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(XIpProperties, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(XIpPropertiesOff, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(GdprDomain, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ParserErrors_, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(GdprGeo_, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(GdprMod_, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(GdprSrc_, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(GdprSafeGeo_, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(GdprSafeMod_, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(GdprSafeSrc_, tmpl, workerId)
    {
    }

    void TGlobalStats::IncParserErrors(TSetCookieSyntaxErrors errs) noexcept {
        errs.ForEachTrue([&](ESetCookieSyntaxError err) {
            ParserErrors_.Inc(err);
        });
    }

    void TGlobalStats::IncGdpr(TGdprStatus v) noexcept {
        GdprGeo_.Inc(EIsGdpr(v.Value.IsGdpr));
        GdprMod_.Inc(v.Value.Mode);
        GdprSrc_.Inc(v.Source);
        GdprSafeGeo_.Inc(EIsGdpr(v.SafeValue.IsGdpr));
        GdprSafeMod_.Inc(v.SafeValue.Mode);
        GdprSafeSrc_.Inc(v.SafeSource);
    }

    void TGlobalStats::OnGdpr(const TExtractedGdpr& gdpr) noexcept {
        GdprCookie.Add(gdpr.Count > 0);
        GdprBadValue.Add(gdpr.BadParse());
        GdprConflict.Add(gdpr.Conflict);
    }

    void TGlobalStats::OnIsGdpr(const TExtractedIsGdpr& isGdpr) noexcept {
        IsGdprCookie.Add(isGdpr.Count > 0);
        IsGdprBadValue.Add(isGdpr.BadParse());
        IsGdprDuplicate.Add(isGdpr.Count > 1);
    }

    void TGlobalStats::OnIsGdprB(const TExtractedIsGdprB& isGdprB) noexcept {
        IsGdprBCookie.Add(isGdprB.Count > 0);
        IsGdprBBadValue.Add(isGdprB.BadParse());
        IsGdprBDuplicate.Add(isGdprB.Count > 1);
    }

    TPolicyStats::TPolicyStats(TString uuid, TSharedStatsManager& manager)
        : Total(MakeCounter({uuid, "total"}, manager))
        , Off(MakeCounter({uuid, "off"}, manager))
        , Pass(MakeCounter({uuid, "pass"}, manager))
        , Fail(MakeCounter({uuid, "fail"}, manager))
        , Fix(MakeCounter({uuid, "fix"}, manager))
        , FixDryRun(MakeCounter({uuid, "fix-dryRun"}, manager))
    {}

    TPolicyStats::TPolicyStats(const TPolicyStats& tmpl, ui32 workerId)
        : Y_BALANCER_INIT_WORKER_COUNTER(Total, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(Off, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(Pass, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(Fail, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(Fix, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(FixDryRun, tmpl, workerId)
    {}

    void TPolicyStats::OnFail(bool dryRun) noexcept {
        Fail.Add(1);
        if (dryRun) {
            FixDryRun.Add(1);
        } else {
            Fix.Add(1);
        }
    }


    TPolicyCookieStats::TPolicyCookieStats(TString uuid, TSharedStatsManager& manager)
        : ReqCookieDrop(MakeCounter({uuid, "req-cookie-drop"}, manager))
        , ReqCookieFix(MakeCounter({uuid, "req-cookie-fix"}, manager))
        , ReqCookieAdd(MakeCounter({uuid, "req-cookie-add"}, manager))
        , ReqCookieDropDryRun(MakeCounter({uuid, "req-cookie-drop-dryRun"}, manager))
        , ReqCookieFixDryRun(MakeCounter({uuid, "req-cookie-fix-dryRun"}, manager))
        , ReqCookieAddDryRun(MakeCounter({uuid, "req-cookie-add-dryRun"}, manager))
        , CookieTotal(MakeCounter({uuid, "cookie-total"}, manager))
        , CookieSkip(MakeCounter({uuid, "cookie-skip"}, manager))
        , CookiePass(MakeCounter({uuid, "cookie-pass"}, manager))
        , CookieFail(MakeCounter({uuid, "cookie-fail"}, manager))
        , CookieDrop(MakeCounter({uuid, "cookie-drop"}, manager))
        , CookieFix(MakeCounter({uuid, "cookie-fix"}, manager))
        , CookieAdd(MakeCounter({uuid, "cookie-add"}, manager))
        , CookieDropDryRun(MakeCounter({uuid, "cookie-drop-dryRun"}, manager))
        , CookieFixDryRun(MakeCounter({uuid, "cookie-fix-dryRun"}, manager))
        , CookieAddDryRun(MakeCounter({uuid, "cookie-add-dryRun"}, manager))
    {}

    TPolicyCookieStats::TPolicyCookieStats(const TPolicyCookieStats& tmpl, ui32 workerId)
        : Y_BALANCER_INIT_WORKER_COUNTER(ReqCookieDrop, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ReqCookieFix, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ReqCookieAdd, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ReqCookieDropDryRun, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ReqCookieFixDryRun, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(ReqCookieAddDryRun, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(CookieTotal, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(CookieSkip, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(CookiePass, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(CookieFail, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(CookieDrop, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(CookieFix, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(CookieAdd, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(CookieDropDryRun, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(CookieFixDryRun, tmpl, workerId)
        , Y_BALANCER_INIT_WORKER_COUNTER(CookieAddDryRun, tmpl, workerId)
    {}
}
