#include <balancer/modules/cookie_policy/ut_common/ut_common.h>

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

using namespace NModCookiePolicy;

Y_UNIT_TEST_SUITE(TPolicyGdprClientCookieTest) {
    namespace {
        auto MakeConfig(bool fix) {
            return MakeCombinedPolicy(Sprintf(R"=(instance={
                uuid="xxx";
                gdpr_controls={
                    deletion_limits={
                        soft_max=8;
                        hard_max=16;
                    };
                };
                gdpr_client_cookie={
                    yyy={
                        %s
                    };
                };
            })=", (fix ? "mode='fix';" : "")));
        }

        auto MakeSoftLimitConfig() {
            return MakeCombinedPolicy(R"=(instance={
                uuid="xxx";
                gdpr_client_cookie={
                    yyy={
                        mode='fix';
                    };
                };
                gdpr_controls={
                    deletion_limits={
                        soft_max=0;
                    };
                };
            })=");
        }

        auto MakeHardLimitConfig() {
            return MakeCombinedPolicy(R"=(instance={
                uuid="xxx";
                gdpr_client_cookie={
                    yyy={
                        mode='fix';
                    };
                };
                gdpr_controls={
                    deletion_limits={
                        hard_max=0;
                    };
                };
            })=");
        }

        auto MakeCookieTypeOverrideConfig() {
            return MakeCombinedPolicy(R"=(instance={
                uuid="xxx";
                gdpr_client_cookie={
                    yyy={
                        mode='fix';
                    };
                };
                gdpr_controls={
                    tech_cookie_re='other_tech';
                };
            })=");
        }
    }

    Y_UNIT_TEST(TestSkipNoGdpr) {
        TInstant now = TInstant::Seconds(1600092462);
        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeConfig(true),
                .Now=now,
                .Path="/zen",
                .Host={"yandex.eu"},
                .Cookie={"i=123; yandexuid=456; whatever_other=789"},
            },
            .Out={
                .Cookie={"i=123; yandexuid=456; whatever_other=789"},
                .ReqLog=" GdprDomain=1",
                .Stats=FixStatsNoGdpr({
                    {"cpol-xxx-gdpr-domain_summ", 1},
                    {"cpol-xxx-yyy-off_summ", 1},
                    {"cpol-xxx-yyy-total_summ", 1},
                }, 0),
            },
        }));
    }

    Y_UNIT_TEST(TestSkipNonGdprRegion) {
        TInstant now = TInstant::Seconds(1600092462);
        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeConfig(true),
                .Now=now,
                .Path="/zen",
                .Host={"yandex.eu"},
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":0,"IsGdprNoVpn":1}
                .Cookie={"gdpr=1; is_gdpr_b=CKeNUxBIKAE=; i=123; yandexuid=456; whatever_other=789"},
            },
            .Out={
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTech,},
                    .SafeValue={.Mode=EGdpr::KeepTech,},
                },
                .Cookie={"gdpr=1; is_gdpr_b=CKeNUxBIKAE=; i=123; yandexuid=456; whatever_other=789"},
                .ReqLog=" GdprDomain=1 Gdpr=1 IsGdprB=0,1",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-domain_summ", 1},
                    {"cpol-xxx-gdpr-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-mod-1_summ", 1},
                    {"cpol-xxx-gdpr-src-IsGdprB_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-0_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-IsGdprB_summ", 1},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                    {"cpol-xxx-yyy-off_summ", 1},
                    {"cpol-xxx-yyy-total_summ", 1},
                }, 0),
            },
        }));
    }

    Y_UNIT_TEST(TestSkipGdprKeepAll) {
        TInstant now = TInstant::Seconds(1600092462);
        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeConfig(true),
                .Now=now,
                .Path="/zen",
                .Host={"yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr=0; i=123; yandexuid=456; whatever_other=789"},
            },
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.IsGdpr=1},
                    .SafeValue={.IsGdpr=1},
                },
                .Cookie={"gdpr=0; i=123; yandexuid=456; whatever_other=789"},
                .ReqLog=" GdprDomain=1 Gdpr=0 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-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-XYandexEURequest_summ", 1},
                    {"cpol-xxx-yyy-off_summ", 1},
                    {"cpol-xxx-yyy-total_summ", 1},
                }, 0),
            },
        }));
    }

    Y_UNIT_TEST(TestSkipGdprNoPopup) {
        TInstant now = TInstant::Seconds(1600092462);
        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeConfig(true),
                .Now=now,
                .Path="/zen",
                .Host={"yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"i=123; yandexuid=456; whatever_other=789"},
            },
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.IsGdpr=1},
                    .SafeValue={.IsGdpr=1},
                },
                .Cookie={"i=123; yandexuid=456; whatever_other=789"},
                .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},
                    {"cpol-xxx-yyy-off_summ", 1},
                    {"cpol-xxx-yyy-total_summ", 1},
                }, 0),
            },
        }));
    }

    Y_UNIT_TEST(TestSkipNoChoiceNoVpnNotEuDomain) {
        // A gdpr region and gdpr popup but no choice, no vpn info, and a non-eu domain
        TInstant now = TInstant::Seconds(1600092462);
        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeConfig(true),
                .Now=now,
                .Path="/zen",
                .Host={"yandex.ru"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr_popup=1; i=123; yandexuid=456; whatever_other=789"},
            },
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTech, .IsGdpr=1,},
                    .SafeValue={.IsGdpr=1},
                },
                .Cookie={"gdpr_popup=1; i=123; yandexuid=456; whatever_other=789"},
                .ReqLog=" GdprPopup=1 XYandexEURequest=1",
                .Stats=FixStats({
                    {"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-GdprPopup-cookie_summ", 1},
                    {"cpol-xxx-GdprPopup-noGdpr_summ", 1},
                    {"cpol-xxx-XYandexEURequest_summ", 1},
                    {"cpol-xxx-yyy-off_summ", 1},
                    {"cpol-xxx-yyy-total_summ", 1},
                }, 0),
            },
        }));
    }

    Y_UNIT_TEST(TestSkipBadHost) {
        TInstant now = TInstant::Seconds(1600092462);
        // A gdpr region and an explicit choice but bad host
        for (auto&& h : std::initializer_list<TStrVec>{{}, {"localhost"}, {"127.0.0.1"}}) {
            Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
                .In={
                    .Cfg=MakeConfig(true),
                    .Now=now,
                    .Path="/zen",
                    .Host=h,
                    .XYandexEURequest={"1"},
                    .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
                },
                .Out={
                    .GeoCache={.XYandexEURequest=1},
                    .Gdpr={
                        .Value={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                        .SafeValue={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                    },
                    .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
                    .ReqLog=" Gdpr=1 XYandexEURequest=1",
                    .Stats=FixStats({
                        {"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},
                        {"cpol-xxx-Gdpr-cookie_summ", 1},
                        {"cpol-xxx-yyy-off_summ", 1},
                        {"cpol-xxx-yyy-total_summ", 1},
                    }, 0),
                },
            }));
        }
    }

    Y_UNIT_TEST(TestGdprKeepTech) {
        TInstant now = TInstant::Seconds(1600092462);
        // A gdpr region and an explicit choice
        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeConfig(true),
                .Now=now,
                .Path="/zen",
                .Host={"zen.yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
            },
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                    .SafeValue={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                },
                .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
                .SetCookie=ToCookie({
                    {.Name="whatever_other", .Path="/", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/zen", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/", .Domain=".zen.yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/zen", .Domain=".zen.yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/", .Domain=".yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/zen", .Domain=".yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                }),
                .ReqLog=" GdprDomain=1 Gdpr=1 XYandexEURequest=1",
                .RespLog=" [cpol u:xxx-yyy fail+fix whatever_other=Add:6!GdprDelete,]",
                .Stats=FixStats({
                    {"cpol-xxx-modified-resp_summ", 1},
                    {"cpol-xxx-gdpr-domain_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},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-yyy-cookie-add_summ", 6},
                    {"cpol-xxx-yyy-fail_summ", 1},
                    {"cpol-xxx-yyy-fix_summ", 1},
                    {"cpol-xxx-yyy-total_summ", 1},
                }, 0),
            },
        }));
    }

    Y_UNIT_TEST(TestGdprChoicePopupEuDomain) {
        TInstant now = TInstant::Seconds(1600092462);
        // A gdpr region, a choice popup and a EU domain
        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeConfig(true),
                .Now=now,
                .Path="/zen",
                .Host={"zen.yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr_popup=1; i=123; yandexuid=456; whatever_other=789"},
            },
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                    .SafeValue={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                },
                .Cookie={"gdpr_popup=1; i=123; yandexuid=456; whatever_other=789"},
                .SetCookie=ToCookie({
                    {.Name="whatever_other", .Path="/", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/zen", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/", .Domain=".zen.yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/zen", .Domain=".zen.yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/", .Domain=".yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/zen", .Domain=".yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                }),
                .ReqLog=" GdprDomain=1 GdprPopup=1 XYandexEURequest=1",
                .RespLog=" [cpol u:xxx-yyy fail+fix whatever_other=Add:6!GdprDelete,]",
                .Stats=FixStats({
                    {"cpol-xxx-modified-resp_summ", 1},
                    {"cpol-xxx-gdpr-domain_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},
                    {"cpol-xxx-GdprPopup-cookie_summ", 1},
                    {"cpol-xxx-GdprPopup-noGdpr_summ", 1},
                    {"cpol-xxx-yyy-cookie-add_summ", 6},
                    {"cpol-xxx-yyy-fail_summ", 1},
                    {"cpol-xxx-yyy-fix_summ", 1},
                    {"cpol-xxx-yyy-total_summ", 1},
                }, 0),
            },
        }));
    }

    Y_UNIT_TEST(TestNoVpnGdprChoicePopup) {
        TInstant now = TInstant::Seconds(1600092462);
        // A non-vpn gdpr region and a choice popup
        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeConfig(true),
                .Now=now,
                .Path="/zen",
                .Host={"zen.yandex.ru"},
                // {"BalancerVerHash":1361575,"Tstamp":1599858000,"IsGdpr":1,"IsGdprNoVpn":1}
                .Cookie={"gdpr_popup=1; is_gdpr_b=CKeNUxBIGAEoAQ==; i=123; yandexuid=456; whatever_other=789"},
            },
            .Out={
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                    .SafeValue={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                },
                .Cookie={"gdpr_popup=1; is_gdpr_b=CKeNUxBIGAEoAQ==; i=123; yandexuid=456; whatever_other=789"},
                .SetCookie=ToCookie({
                    {.Name="whatever_other", .Path="/", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/zen", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/", .Domain=".zen.yandex.ru", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/zen", .Domain=".zen.yandex.ru", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/", .Domain=".yandex.ru", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/zen", .Domain=".yandex.ru", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                }),
                .ReqLog=" GdprPopup=1 IsGdprB=1,1",
                .RespLog=" [cpol u:xxx-yyy fail+fix whatever_other=Add:6!GdprDelete,]",
                .Stats=FixStats({
                    {"cpol-xxx-modified-resp_summ", 1},
                    {"cpol-xxx-gdpr-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-mod-1_summ", 1},
                    {"cpol-xxx-gdpr-src-IsGdprB_summ", 1},
                    {"cpol-xxx-gdpr-safe-geo-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-mod-1_summ", 1},
                    {"cpol-xxx-gdpr-safe-src-IsGdprB_summ", 1},
                    {"cpol-xxx-IsGdprB-cookie_summ", 1},
                    {"cpol-xxx-GdprPopup-cookie_summ", 1},
                    {"cpol-xxx-GdprPopup-noGdpr_summ", 1},
                    {"cpol-xxx-yyy-cookie-add_summ", 6},
                    {"cpol-xxx-yyy-fail_summ", 1},
                    {"cpol-xxx-yyy-fix_summ", 1},
                    {"cpol-xxx-yyy-total_summ", 1},
                }, 0),
            },
        }));
    }

    Y_UNIT_TEST(TestDeletionAppended) {
        TInstant now = TInstant::Seconds(1600092462);
        // Deletion with an existing cookie
        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeConfig(true),
                .Now=now,
                .Path="/zen",
                .Host={"zen.yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
                .SetCookie={"xxx="},
            },
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                    .SafeValue={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                },
                .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
                .SetCookie=ToCookie({
                    {.Name="xxx"},
                    {.Name="whatever_other", .Path="/", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/zen", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/", .Domain=".zen.yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/zen", .Domain=".zen.yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/", .Domain=".yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/zen", .Domain=".yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                }),
                .ReqLog=" GdprDomain=1 Gdpr=1 XYandexEURequest=1",
                .RespLog=" [cpol u:xxx-yyy fail+fix whatever_other=Add:6!GdprDelete,]",
                .Stats=FixStats({
                    {"cpol-xxx-modified-resp_summ", 1},
                    {"cpol-xxx-gdpr-domain_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},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-yyy-cookie-skip_summ", 1},
                    {"cpol-xxx-yyy-cookie-total_summ", 1},
                    {"cpol-xxx-yyy-cookie-add_summ", 6},
                    {"cpol-xxx-yyy-fail_summ", 1},
                    {"cpol-xxx-yyy-fix_summ", 1},
                    {"cpol-xxx-yyy-total_summ", 1},
                }, 1),
            },
        }));
    }

    Y_UNIT_TEST(TestMultipleDeletionsAppended) {
        TInstant now = TInstant::Seconds(1600092462);
        // Testing multiple deletions and existing cookie
        UNIT_ASSERT_VALUES_EQUAL(TestCookiePolicy({
            .Cfg=MakeConfig(true),
            .Now=now,
            .Path="/zen",
            .Host={"zen.yandex.eu"},
            .XYandexEURequest={"1"},
            .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789; whatever_else=xxx"},
            .SetCookie={"xxx="},
        }).SetCookie.size(), 13);
    }

    Y_UNIT_TEST(TestDeletionAppendedDryRun) {
        TInstant now = TInstant::Seconds(1600092462);
        // Deletion with an existing cookie
        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeConfig(false),
                .Now=now,
                .Path="/zen",
                .Host={"zen.yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
                .SetCookie={"xxx="},
            },
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                    .SafeValue={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                },
                .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
                .SetCookie=ToCookie({
                    {.Name="xxx"},
                }),
                .ReqLog=" GdprDomain=1 Gdpr=1 XYandexEURequest=1",
                .RespLog=" [cpol u:xxx-yyy fail+dryRun whatever_other=Add:6!GdprDelete,]",
                .Stats=FixStats({
                    {"cpol-xxx-gdpr-domain_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},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-yyy-cookie-skip_summ", 1},
                    {"cpol-xxx-yyy-cookie-total_summ", 1},
                    {"cpol-xxx-yyy-cookie-add-dryRun_summ", 6},
                    {"cpol-xxx-yyy-fail_summ", 1},
                    {"cpol-xxx-yyy-fix-dryRun_summ", 1},
                    {"cpol-xxx-yyy-total_summ", 1},
                }, 1),
            },
        }));
    }

    Y_UNIT_TEST(TestSoftLimit) {
        TInstant now = TInstant::Seconds(1600092462);

        const TCPTestResult out = {
            .GeoCache={.XYandexEURequest=1},
            .Gdpr={
                .Value={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                .SafeValue={.Mode=EGdpr::KeepTech, .IsGdpr=1},
            },
            .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
            .ReqLog=" GdprDomain=1 Gdpr=1 XYandexEURequest=1",
            .RespLog=" [cpol u:xxx-yyy fail+fix =Add:0!GdprDelete,SoftLimited,]",
            .Stats=FixStats({
                {"cpol-xxx-modified-resp_summ", 1},
                {"cpol-xxx-gdpr-domain_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},
                {"cpol-xxx-Gdpr-cookie_summ", 1},
                {"cpol-xxx-yyy-fail_summ", 1},
                {"cpol-xxx-yyy-fix_summ", 1},
                {"cpol-xxx-yyy-total_summ", 1},
            }, 0),
        };

        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeSoftLimitConfig(),
                .Now=now,
                .Path="/zen",
                .Host={"zen.yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
            },
            .Out=out,
        }));

        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeConfig(true),
                .GdprCtl=R"=({"deletion_limits":{"soft_max":0}})=",
                .Now=now,
                .Path="/zen",
                .Host={"zen.yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
            },
            .Out=out,
        }));
    }

    Y_UNIT_TEST(TestSoftLimitExceeded) {
        TInstant now = TInstant::Seconds(1600092462);
        // Soft limit may be exceeded
        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeConfig(true),
                .GdprCtl=R"=({"deletion_limits":{"soft_max":1}})=",
                .Now=now,
                .Path="/zen",
                .Host={"zen.yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
            },
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                    .SafeValue={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                },
                .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
                .SetCookie=ToCookie({
                    {.Name="whatever_other", .Path="/", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/zen", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/", .Domain=".zen.yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/zen", .Domain=".zen.yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/", .Domain=".yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="whatever_other", .Path="/zen", .Domain=".yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                }),
                .ReqLog=" GdprDomain=1 Gdpr=1 XYandexEURequest=1",
                .RespLog=" [cpol u:xxx-yyy fail+fix whatever_other=Add:6!GdprDelete,SoftLimited,]",
                .Stats=FixStats({
                    {"cpol-xxx-modified-resp_summ", 1},
                    {"cpol-xxx-gdpr-domain_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},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-yyy-cookie-add_summ", 6},
                    {"cpol-xxx-yyy-fail_summ", 1},
                    {"cpol-xxx-yyy-fix_summ", 1},
                    {"cpol-xxx-yyy-total_summ", 1},
                }, 0),
            },
        }));
    }

    Y_UNIT_TEST(TestHardLimit) {
        TInstant now = TInstant::Seconds(1600092462);

        const TCPTestResult out = {
            .GeoCache={.XYandexEURequest=1},
            .Gdpr={
                .Value={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                .SafeValue={.Mode=EGdpr::KeepTech, .IsGdpr=1},
            },
            .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
            .ReqLog=" GdprDomain=1 Gdpr=1 XYandexEURequest=1",
            .RespLog=" [cpol u:xxx-yyy fail+fix =Add:0!GdprDelete,SoftLimited,]",
            .Stats=FixStats({
                {"cpol-xxx-modified-resp_summ", 1},
                {"cpol-xxx-gdpr-domain_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},
                {"cpol-xxx-Gdpr-cookie_summ", 1},
                {"cpol-xxx-yyy-fail_summ", 1},
                {"cpol-xxx-yyy-fix_summ", 1},
                {"cpol-xxx-yyy-total_summ", 1},
            }, 0),
        };

        // The soft limit is adjusted to not to never exceed the hard limit
        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeHardLimitConfig(),
                .Now=now,
                .Path="/zen",
                .Host={"zen.yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
            },
            .Out=out,
        }));

        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeConfig(true),
                .GdprCtl=R"=({"deletion_limits":{"hard_max":0}})=",
                .Now=now,
                .Path="/zen",
                .Host={"zen.yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
            },
            .Out=out,
        }));
    }

    Y_UNIT_TEST(TestHardLimitNotExceeded) {
        TInstant now = TInstant::Seconds(1600092462);
        // Hard limit may not be exceeded
        UNIT_ASSERT_VALUES_EQUAL(TestCookiePolicy({
            .Cfg=MakeConfig(true),
            .GdprCtl=R"=({"deletion_limits":{"hard_max":1}})=",
            .Now=now,
            .Path="/zen",
            .Host={"zen.yandex.eu"},
            .XYandexEURequest={"1"},
            .Cookie={"gdpr=1; i=123; yandexuid=456; whatever_other=789"},
        }).SetCookie.size(), 1);
    }

    Y_UNIT_TEST(TestCookieTypeOverride) {
        TInstant now = TInstant::Seconds(1600092462);

        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeConfig(true),
                .Now=now,
                .Path="/",
                .Host={"yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr=1; i=123; other_tech=456"},
            },
            .Out={
                .GeoCache={.XYandexEURequest=1},
                .Gdpr={
                    .Value={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                    .SafeValue={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                },
                .Cookie={"gdpr=1; i=123; other_tech=456"},
                .SetCookie=ToCookie({
                    {.Name="other_tech", .Path="/", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                    {.Name="other_tech", .Path="/", .Domain=".yandex.eu", .Expires=TExpires::Past(), .MaxAge=0, .Secure=true},
                }),
                .ReqLog=" GdprDomain=1 Gdpr=1 XYandexEURequest=1",
                .RespLog=" [cpol u:xxx-yyy fail+fix other_tech=Add:2!GdprDelete,]",
                .Stats=FixStats({
                    {"cpol-xxx-modified-resp_summ", 1},
                    {"cpol-xxx-gdpr-domain_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},
                    {"cpol-xxx-Gdpr-cookie_summ", 1},
                    {"cpol-xxx-yyy-cookie-add_summ", 2},
                    {"cpol-xxx-yyy-fail_summ", 1},
                    {"cpol-xxx-yyy-fix_summ", 1},
                    {"cpol-xxx-yyy-total_summ", 1},
                }, 0),
            },
        }));

        const auto out = TCPTestResult{
            .GeoCache={.XYandexEURequest=1},
            .Gdpr={
                .Value={.Mode=EGdpr::KeepTech, .IsGdpr=1},
                .SafeValue={.Mode=EGdpr::KeepTech, .IsGdpr=1},
            },
            .Cookie={"gdpr=1; i=123; other_tech=456"},
            .ReqLog=" GdprDomain=1 Gdpr=1 XYandexEURequest=1",
            .Stats=FixStats({
                {"cpol-xxx-gdpr-domain_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},
                {"cpol-xxx-Gdpr-cookie_summ", 1},
                {"cpol-xxx-yyy-pass_summ", 1},
                {"cpol-xxx-yyy-total_summ", 1},
            }, 0),
        };

        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeCookieTypeOverrideConfig(),
                .Now=now,
                .Path="/",
                .Host={"yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr=1; i=123; other_tech=456"},
            },
            .Out=out,
        }));

        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeConfig(true),
                .GdprCtl=R"=({"tech_cookie_re": "other_tech"})=",
                .Now=now,
                .Path="/",
                .Host={"yandex.eu"},
                .XYandexEURequest={"1"},
                .Cookie={"gdpr=1; i=123; other_tech=456"},
            },
            .Out=out,
        }));
    }
}
