#include <balancer/modules/cookie_policy/common/cookie_policy.cfgproto.pb.h>
#include <balancer/modules/cookie_policy/common/gdpr_controls.h>
#include <balancer/modules/cookie_policy/common/gdpr.h>
#include <balancer/modules/cookie_policy/ut_common/ut_common.h>

#include <balancer/kernel/testing/conn_descr.h>
#include <balancer/kernel/testing/process_mock.h>

#include <library/cpp/testing/unittest/registar.h>

using namespace NModCookiePolicy;
using namespace NSrvKernel::NTesting;


Y_UNIT_TEST_SUITE(TGdprTest) {
    auto GenCookies(TStringBuf cookie) {
        TVector<TRequestCookie> res;
        EveryCookieKV([&](TNameValue nv) {
            res.emplace_back(TRequestCookie{.NameValue=nv});
        }, cookie);
        return res;
    }

    Y_UNIT_TEST(TestExractGdprCookie) {
        UNIT_ASSERT_VALUES_EQUAL(ExtractGdprCookie(GenCookies({})), TExtractedGdpr{});
        UNIT_ASSERT_VALUES_EQUAL(ExtractGdprCookie(GenCookies("gdpr=4")), (TExtractedGdpr{
            .Count=1,
        }));
        UNIT_ASSERT_VALUES_EQUAL(ExtractGdprCookie(GenCookies("gdpr=0")), (TExtractedGdpr{
            .Parsed=EGdpr::KeepAll,
            .Count=1,
        }));
        UNIT_ASSERT_VALUES_EQUAL(ExtractGdprCookie(GenCookies("gdpr=0; gdpr=0")), (TExtractedGdpr{
            .Parsed=EGdpr::KeepAll,
            .Count=2,
        }));
        UNIT_ASSERT_VALUES_EQUAL(ExtractGdprCookie(GenCookies("gdpr=0; gdpr=3")), (TExtractedGdpr{
            .Parsed=EGdpr::KeepAll,
            .Count=2,
            .Conflict=1,
        }));
        UNIT_ASSERT_VALUES_EQUAL(ExtractGdprCookie(GenCookies("gdpr=1; gdpr=2")), (TExtractedGdpr{
            .Parsed=EGdpr::KeepTechAnalytic,
            .Count=2,
            .Conflict=1,
        }));
        UNIT_ASSERT_VALUES_EQUAL(ExtractGdprCookie(GenCookies("gdpr=1; gdpr=2; gdpr=3")), (TExtractedGdpr{
            .Parsed=EGdpr::KeepTechOther,
            .Count=3,
            .Conflict=1,
        }));
    }

    Y_UNIT_TEST(TestExractIsGdprCookie) {
        UNIT_ASSERT_VALUES_EQUAL(ExtractIsGdprCookie(GenCookies({})), TExtractedIsGdpr{});
        UNIT_ASSERT_VALUES_EQUAL(ExtractIsGdprCookie(GenCookies("is_gdpr=2")), (TExtractedIsGdpr{
            .Count=1,
        }));
        UNIT_ASSERT_VALUES_EQUAL(ExtractIsGdprCookie(GenCookies("is_gdpr=1")), (TExtractedIsGdpr{
            .Parsed=EIsGdpr::True,
            .Count=1,
        }));
        UNIT_ASSERT_VALUES_EQUAL(ExtractIsGdprCookie(GenCookies("is_gdpr=0; is_gdpr=0")), (TExtractedIsGdpr{
            .Parsed=EIsGdpr::False,
            .Count=2,
        }));
        UNIT_ASSERT_VALUES_EQUAL(ExtractIsGdprCookie(GenCookies("is_gdpr=0; is_gdpr=1")), (TExtractedIsGdpr{
            .Parsed=EIsGdpr::False,
            .Count=2,
            .Conflict=1,
        }));
    }

    Y_UNIT_TEST(TestExtractIsGdprBCookie) {
        UNIT_ASSERT_VALUES_EQUAL(ExtractIsGdprBCookie(GenCookies({})), TExtractedIsGdprB{});
        UNIT_ASSERT_VALUES_EQUAL(ExtractIsGdprBCookie(GenCookies("is_gdpr_b=CKeNUxBG")), (TExtractedIsGdprB{
            .Parsed=TIsGdprB{
                .BalancerVerHash=1361575,
                .Tstamp=TInstant::Seconds(1599850800),
            },
            .Count=1,
        }));
        UNIT_ASSERT_VALUES_EQUAL(ExtractIsGdprBCookie(GenCookies("is_gdpr_b=CKeNUxBGGAEoAQ==")), (TExtractedIsGdprB{
            .Parsed=TIsGdprB{
                .BalancerVerHash=1361575,
                .Tstamp=TInstant::Seconds(1599850800),
                .IsGdpr=true,
                .IsGdprNoVpn=true,
            },
            .Count=1,
        }));
        UNIT_ASSERT_VALUES_EQUAL(ExtractIsGdprBCookie(GenCookies("is_gdpr_b=CKeNUxBGKAI=; is_gdpr_b=CKeNUxBGKAI=")), (TExtractedIsGdprB{
            .Parsed=TIsGdprB{
                .BalancerVerHash=1361575,
                .Tstamp=TInstant::Seconds(1599850800),
                .IsGdpr=false,
                .IsGdprNoVpn=false,
            },
            .Count=2,
        }));
        UNIT_ASSERT_VALUES_EQUAL(ExtractIsGdprBCookie(GenCookies("is_gdpr_b=CKeNUxBHGAE=; is_gdpr_b=CKeNUxBG")), (TExtractedIsGdprB{
            .Parsed=TIsGdprB{
                .BalancerVerHash=1361575,
                .Tstamp=TInstant::Seconds(1599854400),
                .IsGdpr=true,
            },
            .Count=2,
            .Conflict=1,
        }));
    }

    struct TGdprControlsCfgSimple {
        TMaybe<bool> use_is_gdpr_b;
        TMaybe<bool> use_x_yandex_eu_request;
        TMaybe<bool> use_x_ip_properties;
        TMaybe<ui32> banned_is_gdpr_b;
    };

#define Y_COOKIE_POLICY_SET_CFG_FIELD(from, to, name) if (from.name) { to.set_ ## name(*from.name); }

    TGdprControlsCfg MakeGdprControls(const TGdprControlsCfgSimple& c) {
        TGdprControlsCfg cfg;
        Y_COOKIE_POLICY_SET_CFG_FIELD(c, cfg, use_is_gdpr_b);
        Y_COOKIE_POLICY_SET_CFG_FIELD(c, cfg, use_x_yandex_eu_request);
        Y_COOKIE_POLICY_SET_CFG_FIELD(c, cfg, use_x_ip_properties);
        if (c.banned_is_gdpr_b) {
            cfg.mutable_banned_is_gdpr_b()->add_items()->set_balancer_ver_hash(*c.banned_is_gdpr_b);
        }
        return cfg;
    }

    struct TGdprTestCase {
        struct TIn {
            TGdprCache GeoCache;
            TMaybe<TGdprControlsCfgSimple> Cfg;
            TString DynCfg;
            TInstant Now;
            TStrVec Host;
            TStrVec XYandexEURequest;
            TStrVec XIpProperties;
            TStrVec Cookie;
        } In;
        struct TOut {
            TGdprCache GeoCache;
            TGdpr Gdpr;
            TStrVec Cookie;
            TString ReqLog;
            TStatsVec Stats;
        } Out;
    };

    TCPTestInput TestInput(const TGdprTestCase::TIn& c) {
        TCPTestInput in = {
            .GdprCtl=c.DynCfg,
            .GeoCache=c.GeoCache,
            .Now=c.Now,
            .Host=c.Host,
            .XYandexEURequest=c.XYandexEURequest,
            .XIpProperties=c.XIpProperties,
            .Cookie=c.Cookie,
        };
        in.Cfg.set_uuid("xxx");
        if (c.Cfg) {
            in.Cfg.set_gdpr_controls(MakeGdprControls(*c.Cfg));
        }
        return in;
    }

    TCPTestResult TestResult(const TGdprTestCase::TOut& c) {
        return {
            .GeoCache=c.GeoCache,
            .Gdpr=c.Gdpr,
            .Cookie=c.Cookie,
            .ReqLog=c.ReqLog,
            .Stats=c.Stats,
        };
    }

    void DoTestGdpr(const TGdprTestCase& c, TSourceLocation loc) {
        UNIT_ASSERT_VALUES_EQUAL_C(TestCookiePolicy(TestInput(c.In)), TestResult(c.Out), loc);
    }

#define Y_COOKIE_POLICY_TEST_GDPR(c) DoTestGdpr(c, __LOCATION__)

    Y_UNIT_TEST(TestNoGeo) {
        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .Out={
                .Stats=FixStatsNoGdpr({}, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Cookie={"gdpr=2"},
            },
            .Out={
                .Cookie={"gdpr=2"},
                .ReqLog=" Gdpr=2",
                .Stats=FixStatsNoGdpr({
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                }, 0),
            }
        }));
    }

    Y_UNIT_TEST(TestXYandexEURequestOff) {
        TGdprTestCase::TOut out = {
            .ReqLog=" XYandexEURequest:off",
            .Stats=FixStatsNoGdpr({
                {"cpol-xxx-XYandexEURequest_summ", 1},
                {"cpol-xxx-XYandexEURequest-off_summ", 1},
            }, 0),
        };

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Cfg=TGdprControlsCfgSimple{
                    .use_x_yandex_eu_request=false,
                },
                .XYandexEURequest={"1"},
            },
            .Out=out
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Cfg=TGdprControlsCfgSimple{
                    .use_x_yandex_eu_request=true,
                },
                .DynCfg=R"=({"use_x_yandex_eu_request":0})=",
                .XYandexEURequest={"1"},
            },
            .Out=out
        }));
    }

    Y_UNIT_TEST(TestXYandexEURequest) {
        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={.XYandexEURequest={"0"}},
            .Out={
                .GeoCache={.XYandexEURequest=0},
                .ReqLog=" XYandexEURequest=0",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-XYandexEURequest_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={.XYandexEURequest={"1"}},
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepAll, .IsGdpr=true,},
                    .SafeValue={.Mode=EGdpr::KeepAll, .IsGdpr=true,},
                },
                .ReqLog=" XYandexEURequest=1",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-XYandexEURequest_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Host={"yandex.eu"},
                .XYandexEURequest={"1"},
            },
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepAll, .IsGdpr=true,},
                    .SafeValue={.Mode=EGdpr::KeepAll, .IsGdpr=true,},
                },
                .ReqLog=" GdprDomain=1 XYandexEURequest=1",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-domain_summ", 1},
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-XYandexEURequest_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Host={"yandex.ru"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr_popup=1"},
            },
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTech, .IsGdpr=true,},
                    .SafeValue={.Mode=EGdpr::KeepAll, .IsGdpr=true,},
                },
                .Cookie={"gdpr_popup=1"},
                .ReqLog=" GdprPopup=1 XYandexEURequest=1",
                .Stats=FixStats({
                    {"cpol-xxx-GdprPopup-cookie_summ", 1},
                    {"cpol-xxx-GdprPopup-noGdpr_summ", 1},
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-1_summ", 1},
                    {"cpol-xxx-gdpr-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-XYandexEURequest_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Host={"yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr_popup=1"},
            },
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTech, .IsGdpr=true,},
                    .SafeValue={.Mode=EGdpr::KeepTech, .IsGdpr=true,},
                },
                .Cookie={"gdpr_popup=1"},
                .ReqLog=" GdprDomain=1 GdprPopup=1 XYandexEURequest=1",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-domain_summ", 1},
                    {"cpol-xxx-GdprPopup-cookie_summ", 1},
                    {"cpol-xxx-GdprPopup-noGdpr_summ", 1},
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-1_summ", 1},
                    {"cpol-xxx-gdpr-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-XYandexEURequest_summ", 1},
                }, 0),
            }
        }));
    }

    Y_UNIT_TEST(TestXYandexEURequestGdpr) {
        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .XYandexEURequest={"0"},
                .Cookie={"gdpr=2"},
            },
            .Out={
                .GeoCache={.XYandexEURequest=0},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTechAnalytic,},
                    .SafeValue={.Mode=EGdpr::KeepTechAnalytic,},
                },
                .Cookie={"gdpr=2"},
                .ReqLog=" Gdpr=2 XYandexEURequest=0",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-mod-2_summ", 1},
                    {"cpol-xxx-gdpr-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-2_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-XYandexEURequest_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .XYandexEURequest={"0"},
                .Cookie={"gdpr=1; gdpr=2; gdpr=3; gdpr=2; gdpr=1"},
            },
            .Out={
                .GeoCache={.XYandexEURequest=0},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTechOther,},
                    .SafeValue={.Mode=EGdpr::KeepTechOther,},
                },
                .Cookie={"gdpr=1; gdpr=2; gdpr=3; gdpr=2; gdpr=1"},
                .ReqLog=" Gdpr=3 XYandexEURequest=0",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-mod-3_summ", 1},
                    {"cpol-xxx-gdpr-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-3_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-Gdpr-conflict_summ", 1},
                    {"cpol-xxx-XYandexEURequest_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .XYandexEURequest={"0"},
                .Cookie={"gdpr=1; gdpr=2; gdpr=3; gdpr=xxx; gdpr=0; gdpr=xxx; gdpr=3; gdpr=2; gdpr=1"},
            },
            .Out={
                .GeoCache={.XYandexEURequest=0},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepAll,},
                    .SafeValue={.Mode=EGdpr::KeepAll,},
                },
                .Cookie={"gdpr=1; gdpr=2; gdpr=3; gdpr=xxx; gdpr=0; gdpr=xxx; gdpr=3; gdpr=2; gdpr=1"},
                .ReqLog=" Gdpr=0 XYandexEURequest=0",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-Gdpr-conflict_summ", 1},
                    {"cpol-xxx-XYandexEURequest_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .XYandexEURequest={"1"},
                .Cookie={"gdpr=2"},
            },
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTechAnalytic, .IsGdpr=true,},
                    .SafeValue={.Mode=EGdpr::KeepTechAnalytic, .IsGdpr=true,},
                },
                .Cookie={"gdpr=2"},
                .ReqLog=" Gdpr=2 XYandexEURequest=1",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-2_summ", 1},
                    {"cpol-xxx-gdpr-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-2_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-XYandexEURequest_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Host={"yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr=2"},
            },
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTechAnalytic, .IsGdpr=true,},
                    .SafeValue={.Mode=EGdpr::KeepTechAnalytic, .IsGdpr=true,},
                },
                .Cookie={"gdpr=2"},
                .ReqLog=" GdprDomain=1 Gdpr=2 XYandexEURequest=1",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-domain_summ", 1},
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-2_summ", 1},
                    {"cpol-xxx-gdpr-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-2_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-XYandexEURequest_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Host={"yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr_popup=1; gdpr=2"},
            },
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTechAnalytic, .IsGdpr=true,},
                    .SafeValue={.Mode=EGdpr::KeepTechAnalytic, .IsGdpr=true,},
                },
                .Cookie={"gdpr_popup=1; gdpr=2"},
                .ReqLog=" GdprDomain=1 Gdpr=2 GdprPopup=1 XYandexEURequest=1",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-domain_summ", 1},
                    {"cpol-xxx-GdprPopup-cookie_summ", 1},
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-2_summ", 1},
                    {"cpol-xxx-gdpr-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-2_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-XYandexEURequest_summ", 1},
                }, 0),
            }
        }));
    }
    Y_UNIT_TEST(TestXIpPropertiesOff) {
        TGdprTestCase::TOut out = {
            .ReqLog=" XIpProperties:off",
            .Stats=FixStatsNoGdpr({
                {"cpol-xxx-XIpProperties_summ", 1},
                {"cpol-xxx-XIpProperties-off_summ", 1},
            }, 0),
        };

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Cfg=TGdprControlsCfgSimple{
                    .use_x_ip_properties=false,
                },
                .XIpProperties={"OABAAA=="},
            },
            .Out=out
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Cfg=TGdprControlsCfgSimple{
                    .use_x_yandex_eu_request=true,
                },
                .DynCfg=R"=({"use_x_ip_properties":0})=",
                .XIpProperties={"OABAAA=="},
            },
            .Out=out
        }));
    }

    Y_UNIT_TEST(TestXIpProperties) {
        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .XIpProperties={"OABAAA=="},
            },
            .Out={
                .GeoCache={.XIpProperties=TXIpProperties{.IsGdpr=0, .IsVpn=0},},
                .ReqLog=" XIpProperties=0,0",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-src-XIpProperties_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XIpProperties_summ", 1},
                    {"cpol-xxx-XIpProperties_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .XIpProperties={"OABAAQ=="},
            },
            .Out={
                .GeoCache={.XIpProperties=TXIpProperties{.IsGdpr=1, .IsVpn=0},},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepAll, .IsGdpr=true,},
                    .SafeValue={.Mode=EGdpr::KeepAll, .IsGdpr=true,},
                },
                .ReqLog=" XIpProperties=1,1",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-src-XIpProperties_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XIpProperties_summ", 1},
                    {"cpol-xxx-XIpProperties_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Host={"yandex.eu"},
                .XIpProperties={"OABAAQ=="},
            },
            .Out={
                .GeoCache={.XIpProperties=TXIpProperties{.IsGdpr=1, .IsVpn=0},},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepAll, .IsGdpr=true,},
                    .SafeValue={.Mode=EGdpr::KeepAll, .IsGdpr=true,},
                },
                .ReqLog=" GdprDomain=1 XIpProperties=1,1",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-domain_summ", 1},
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-src-XIpProperties_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XIpProperties_summ", 1},
                    {"cpol-xxx-XIpProperties_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Host={"yandex.ru"},
                .XIpProperties={"OABAAQ=="},
                .Cookie={"gdpr_popup=1"},
            },
            .Out={
                .GeoCache={.XIpProperties=TXIpProperties{.IsGdpr=1, .IsVpn=0},},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTech, .IsGdpr=true,},
                    .SafeValue={.Mode=EGdpr::KeepTech, .IsGdpr=true,},
                },
                .Cookie={"gdpr_popup=1"},
                .ReqLog=" GdprPopup=1 XIpProperties=1,1",
                .Stats=FixStats({
                    {"cpol-xxx-GdprPopup-cookie_summ", 1},
                    {"cpol-xxx-GdprPopup-noGdpr_summ", 1},
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-1_summ", 1},
                    {"cpol-xxx-gdpr-src-XIpProperties_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XIpProperties_summ", 1},
                    {"cpol-xxx-XIpProperties_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Host={"yandex.eu"},
                .XIpProperties={"OABAAQ=="},
                .Cookie={"gdpr_popup=1"}
            },
            .Out={
                .GeoCache={.XIpProperties=TXIpProperties{.IsGdpr=1, .IsVpn=0},},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTech, .IsGdpr=true,},
                    .SafeValue={.Mode=EGdpr::KeepTech, .IsGdpr=true,},
                },
                .Cookie={"gdpr_popup=1"},
                .ReqLog=" GdprDomain=1 GdprPopup=1 XIpProperties=1,1",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-domain_summ", 1},
                    {"cpol-xxx-GdprPopup-cookie_summ", 1},
                    {"cpol-xxx-GdprPopup-noGdpr_summ", 1},
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-1_summ", 1},
                    {"cpol-xxx-gdpr-src-XIpProperties_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XIpProperties_summ", 1},
                    {"cpol-xxx-XIpProperties_summ", 1},
                }, 0),
            }
        }));
    }

    Y_UNIT_TEST(TestIsGdprBOff) {
        const auto now = TInstant::Seconds(1599858615);
        TGdprTestCase::TOut out ={
            .Cookie={"is_gdpr_b=CKeNUxBI"},
            .ReqLog=" IsGdprB:off",
            .Stats=FixStatsNoGdpr({
                {"cpol-xxx-IsGdprB-off_summ", 1},
                {"cpol-xxx-IsGdprB-cookie_summ", 1},
            }, 0),
        };

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Cfg=TGdprControlsCfgSimple{.use_is_gdpr_b=0},
                .Now=now,
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":0}
                .Cookie={"is_gdpr_b=CKeNUxBI"},
            },
            .Out=out,
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Cfg=TGdprControlsCfgSimple{.use_is_gdpr_b=1},
                .DynCfg=R"=({"use_is_gdpr_b":0})=",
                .Now=now,
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":0}
                .Cookie={"is_gdpr_b=CKeNUxBI"},
            },
            .Out=out,
        }));
    }

    Y_UNIT_TEST(TestIsGdprBFiltering) {
        const auto now = TInstant::Seconds(1599858615);
        TStatsVec stats = FixStatsNoGdpr({
            {"cpol-xxx-IsGdprB-filtered_summ", 1},
            {"cpol-xxx-IsGdprB-cookie_summ", 1},
        }, 0);

        TGdprTestCase::TOut out = {
            .Cookie={"is_gdpr_b=CKeNUxBI"},
            .ReqLog=" IsGdprB:filtered",
            .Stats=stats,
        };

        // Tstamp from the future
        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now - TDuration::Days(1),
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":0}
                .Cookie={"is_gdpr_b=CKeNUxBI"},
            },
            .Out=out,
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Cfg=TGdprControlsCfgSimple{.banned_is_gdpr_b=1361575},
                .Now=now,
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":0}
                .Cookie={"is_gdpr_b=CKeNUxBI"},
            },
            .Out=out,
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .DynCfg=R"=({"banned_is_gdpr_b":{"items":[{"balancer_ver_hash":1361575}]}})=",
                .Now=now,
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":0}
                .Cookie={"is_gdpr_b=CKeNUxBI"},
            },
            .Out=out,
        }));

        // Too old tstamp
        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                // {"BalancerVerHash":1,"Tstamp":1599598800,"IsGdpr":0}
                .Cookie={"is_gdpr_b=CAE="},
            },
            .Out={
                .Cookie={"is_gdpr_b=CAE="},
                .ReqLog=" IsGdprB:filtered",
                .Stats=stats,
            },
        }));

        // Zero hash
        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                // {"BalancerVerHash":0,"Tstamp":1599602400,"IsGdpr":0}
                .Cookie={"is_gdpr_b=EAE="},
            },
            .Out={
                .Cookie={"is_gdpr_b=EAE="},
                .ReqLog=" IsGdprB:filtered",
                .Stats=stats,
            },
        }));

        // Invalid base64
        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                .Cookie={"is_gdpr_b=xxxxx"},
            },
            .Out={
                .Cookie={"is_gdpr_b=xxxxx"},
                .ReqLog=" IsGdprB:badValue",
                .Stats=FixStatsNoGdpr({
                    {"cpol-xxx-IsGdprB-badValue_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                }, 0),
            },
        }));
    }

    Y_UNIT_TEST(TestIsGdprB) {
        const auto now = TInstant::Seconds(1599858615);
        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":0}
                .Cookie={"is_gdpr_b=CKeNUxBI"},
            },
            .Out={
                .Cookie={"is_gdpr_b=CKeNUxBI"},
                .ReqLog=" IsGdprB=0,?",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-src-IsGdprB_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-IsGdprB_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":1,"IsGdprNoVpn":0}
                .Cookie={"is_gdpr_b=CKeNUxBIGAEoAg=="},
            },
            .Out={
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepAll, .IsGdpr=true},
                    .SafeValue={.Mode=EGdpr::KeepAll, .IsGdpr=false},
                },
                .Cookie={"is_gdpr_b=CKeNUxBIGAEoAg=="},
                .ReqLog=" IsGdprB=1,0",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-src-IsGdprB_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-IsGdprB_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":0,"IsGdprNoVpn":1}
                .Cookie={"is_gdpr_b=CKeNUxBIKAE="},
            },
            .Out={
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepAll, .IsGdpr=false},
                    .SafeValue={.Mode=EGdpr::KeepAll, .IsGdpr=false},
                },
                .Cookie={"is_gdpr_b=CKeNUxBIKAE="},
                .ReqLog=" IsGdprB=0,1",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-src-IsGdprB_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-IsGdprB_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":1,"IsGdprNoVpn":1}
                .Cookie={"is_gdpr_b=CKeNUxBIGAEoAQ=="},
            },
            .Out={
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepAll, .IsGdpr=true},
                    .SafeValue={.Mode=EGdpr::KeepAll, .IsGdpr=true},
                },
                .Cookie={"is_gdpr_b=CKeNUxBIGAEoAQ=="},
                .ReqLog=" IsGdprB=1,1",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-src-IsGdprB_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-IsGdprB_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                }, 0),
            }
        }));
    }

    Y_UNIT_TEST(TestIsGdprBGdpr) {
        const auto now = TInstant::Seconds(1599858615);
        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":0}
                .Cookie={"is_gdpr_b=CKeNUxBI; gdpr=2"},
            },
            .Out={
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTechAnalytic},
                    .SafeValue={.Mode=EGdpr::KeepTechAnalytic},
                },
                .Cookie={"is_gdpr_b=CKeNUxBI; gdpr=2"},
                .ReqLog=" Gdpr=2 IsGdprB=0,?",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-mod-2_summ", 1},
                    {"cpol-xxx-gdpr-src-IsGdprB_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-2_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-IsGdprB_summ", 1},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":1,"IsGdprNoVpn":0}
                .Cookie={"is_gdpr_b=CKeNUxBIGAEoAg==; gdpr=2"},
            },
            .Out={
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTechAnalytic, .IsGdpr=true},
                    .SafeValue={.Mode=EGdpr::KeepTechAnalytic, .IsGdpr=false},
                },
                .Cookie={"is_gdpr_b=CKeNUxBIGAEoAg==; gdpr=2"},
                .ReqLog=" Gdpr=2 IsGdprB=1,0",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-2_summ", 1},
                    {"cpol-xxx-gdpr-src-IsGdprB_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-2_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-IsGdprB_summ", 1},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":0,"IsGdprNoVpn":1}
                .Cookie={"is_gdpr_b=CKeNUxBIKAE=; gdpr=2"},
            },
            .Out={
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTechAnalytic, .IsGdpr=false},
                    .SafeValue={.Mode=EGdpr::KeepTechAnalytic, .IsGdpr=false},
                },
                .Cookie={"is_gdpr_b=CKeNUxBIKAE=; gdpr=2"},
                .ReqLog=" Gdpr=2 IsGdprB=0,1",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-mod-2_summ", 1},
                    {"cpol-xxx-gdpr-src-IsGdprB_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-2_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-IsGdprB_summ", 1},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":1,"IsGdprNoVpn":1}
                .Cookie={"is_gdpr_b=CKeNUxBIGAEoAQ==; gdpr=2"},
            },
            .Out={
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTechAnalytic, .IsGdpr=true},
                    .SafeValue={.Mode=EGdpr::KeepTechAnalytic, .IsGdpr=true},
                },
                .Cookie={"is_gdpr_b=CKeNUxBIGAEoAQ==; gdpr=2"},
                .ReqLog=" Gdpr=2 IsGdprB=1,1",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-2_summ", 1},
                    {"cpol-xxx-gdpr-src-IsGdprB_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-2_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-IsGdprB_summ", 1},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                }, 0),
            }
        }));
    }

    Y_UNIT_TEST(TestIsGdprBvsXYandexEURequest) {
        const auto now = TInstant::Seconds(1599858615);
        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                .XYandexEURequest={"1"},
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":0}
                .Cookie={"is_gdpr_b=CKeNUxBI"},
            },
            .Out={
                .GeoCache={
                    .XYandexEURequest=1,
                },
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepAll,.IsGdpr=1,},
                    .SafeValue={.Mode=EGdpr::KeepAll,.IsGdpr=1,},
                },
                .Cookie={"is_gdpr_b=CKeNUxBI"},
                .ReqLog=" XYandexEURequest=1 IsGdprB=0,?",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                    {"cpol-xxx-XYandexEURequest_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                .XYandexEURequest={"0"},
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":1,"IsGdprNoVpn":1}
                .Cookie={"is_gdpr_b=CKeNUxBIGAEoAQ=="},
            },
            .Out={
                .GeoCache={.XYandexEURequest=0},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepAll, .IsGdpr=false},
                    .SafeValue={.Mode=EGdpr::KeepAll, .IsGdpr=false},
                },
                .Cookie={"is_gdpr_b=CKeNUxBIGAEoAQ=="},
                .ReqLog=" XYandexEURequest=0 IsGdprB=1,1",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                    {"cpol-xxx-XYandexEURequest_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                .XYandexEURequest={"1"},
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":1,"IsGdprNoVpn":1}
                .Cookie={"is_gdpr_b=CKeNUxBIGAEoAQ=="},
            },
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepAll, .IsGdpr=true},
                    .SafeValue={.Mode=EGdpr::KeepAll, .IsGdpr=true},
                },
                .Cookie={"is_gdpr_b=CKeNUxBIGAEoAQ=="},
                .ReqLog=" XYandexEURequest=1 IsGdprB=1,1",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-src-XYandexEURequest_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-IsGdprB_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                    {"cpol-xxx-XYandexEURequest_summ", 1},
                }, 0),
            }
        }));
    }

    Y_UNIT_TEST(TestIsGdprBvsXIpProperties) {
        const auto now = TInstant::Seconds(1599858615);
        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                .XIpProperties={"OAFAAQ=="},
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":1,"IsGdprNoVpn":0}
                .Cookie={"is_gdpr_b=CKeNUxBIGAEoAg=="},
            },
            .Out={
                .GeoCache={
                    .XIpProperties=TXIpProperties{.IsGdpr=1, .IsVpn=1},
                },
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepAll,.IsGdpr=1,},
                    .SafeValue={.Mode=EGdpr::KeepAll,.IsGdpr=0,},
                },
                .Cookie={"is_gdpr_b=CKeNUxBIGAEoAg=="},
                .ReqLog=" XIpProperties=1,? IsGdprB=1,0",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-src-XIpProperties_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-IsGdprB_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                    {"cpol-xxx-XIpProperties_summ", 1},
                }, 0),
            }
        }));

        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                .XIpProperties={"OABAAQ=="},
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":0}
                .Cookie={"is_gdpr_b=CKeNUxBI"},
            },
            .Out={
                .GeoCache={
                    .XIpProperties=TXIpProperties{.IsGdpr=1, .IsVpn=0},
                },
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepAll,.IsGdpr=1,},
                    .SafeValue={.Mode=EGdpr::KeepAll,.IsGdpr=1,},
                },
                .Cookie={"is_gdpr_b=CKeNUxBI"},
                .ReqLog=" XIpProperties=1,1 IsGdprB=0,?",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-src-XIpProperties_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-XIpProperties_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                    {"cpol-xxx-XIpProperties_summ", 1},
                }, 0),
            }
        }));


    }

    Y_UNIT_TEST(TestInvalidValues) {
        const auto now = TInstant::Seconds(1599858615);
        Y_COOKIE_POLICY_TEST_GDPR((TGdprTestCase{
            .In={
                .Now=now,
                .XYandexEURequest={"z"},
                .XIpProperties={"z"},
                .Cookie={"gdpr=z; gdpr_popup=z; is_gdpr_b=z; is_gdpr=z"},
            },
            .Out={
                .Cookie={"gdpr=z; gdpr_popup=z; is_gdpr_b=z; is_gdpr=z"},
                .ReqLog=" Gdpr:badValue IsGdprB:badValue",
                .Stats=FixStatsNoGdpr({
                    {"cpol-xxx-Gdpr-badValue_summ", 1},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-IsGdpr-badValue_summ", 1},
                    {"cpol-xxx-IsGdpr-cookie_summ", 1},
                    {"cpol-xxx-IsGdprB-badValue_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                }, 0),
            }
        }));
    }
}
