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

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

#include <util/string/printf.h>

using namespace NModCookiePolicy;

Y_UNIT_TEST_SUITE(TPolicySameSiteNoneTest) {
    namespace {
        auto MakeSimpleConfig(bool fix) {
            return MakeCombinedPolicy(Sprintf(R"=(instance={
                uuid="xxx";
                samesite_none={
                    yyy={
                        %s
                    };
                };
            })=", (fix ? "mode='fix'" : "")));
        }

        auto MakeNameReConfig(bool fix) {
            return MakeCombinedPolicy(Sprintf(R"=(instance={
                uuid="xxx";
                samesite_none={
                    yyy={
                        name_re="Ss.*";
                        %s
                    };
                };
            })=", (fix ? "mode='fix'" : "")));
        }

        auto CookieSimple() {
            return ToCookie({
                {.Name="SsUndefined"},
                {.Name="SsNone", .SameSite=ESameSite::None},
                {.Name="SsNoneSec", .SameSite=ESameSite::None, .Secure=true},
                {.Name="SsLax", .SameSite=ESameSite::Lax},
                {.Name="SsStrict", .SameSite=ESameSite::Strict},
            });
        }

        auto CookieNameRe() {
            return ToCookie({
                {.Name="SsUndefined"},
                {.Name="SsNone", .SameSite=ESameSite::None},
                {.Name="SsNoneSec", .SameSite=ESameSite::None, .Secure=true},
                {.Name="SsLax", .SameSite=ESameSite::Lax},
                {.Name="SsStrict", .SameSite=ESameSite::Strict},
                {.Name="NoMatchNone", .SameSite=ESameSite::None},
                {.Name="NoMatchLax", .SameSite=ESameSite::Lax},
            });
        }
    }

    Y_UNIT_TEST(TestNoSupport) {
        // No user-agent should work the same way a not supporting user-agent
        for (auto ua : {TStrVec{}, TStrVec{TString(FirefoxUA)}}) {
            Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
                .In={
                    .Cfg=MakeSimpleConfig(true),
                    .UserAgent=ua,
                    .SetCookie=CookieSimple(),
                },
                .Out={
                    .SetCookie=ToCookie({
                        {.Name="SsUndefined"},
                        {.Name="SsNone"},
                        {.Name="SsNoneSec", .Secure=true},
                        {.Name="SsLax", .SameSite=ESameSite::Lax},
                        {.Name="SsStrict", .SameSite=ESameSite::Strict}
                    }),
                    .RespLog=" [cpol u:xxx-yyy fail+fix SsNone=Fix:1!BadSameSite, SsNoneSec=Fix:1!BadSameSite,]",
                    .Stats=FixStatsNoGdpr({
                        {"cpol-xxx-modified-resp_summ", 1},
                        {"cpol-xxx-yyy-cookie-fail_summ", 2},
                        {"cpol-xxx-yyy-cookie-fix_summ", 2},
                        {"cpol-xxx-yyy-cookie-skip_summ", 3},
                        {"cpol-xxx-yyy-cookie-total_summ", 5},
                        {"cpol-xxx-yyy-fail_summ", 1},
                        {"cpol-xxx-yyy-fix_summ", 1},
                        {"cpol-xxx-yyy-total_summ", 1},
                    }, CookieSimple().size()),
                },
            }));
        }
    }

    Y_UNIT_TEST(TestNoSupportDryRun) {
        // No user-agent should work the same way a not supporting user-agent
        for (auto ua : {TStrVec{}, TStrVec{TString(FirefoxUA)}}) {
            Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
                .In={
                    .Cfg=MakeSimpleConfig(false),
                    .UserAgent=ua,
                    .SetCookie=CookieSimple(),
                },
                .Out={
                    .SetCookie=CookieSimple(),
                    .RespLog=" [cpol u:xxx-yyy fail+dryRun SsNone=Fix:1!BadSameSite, SsNoneSec=Fix:1!BadSameSite,]",
                    .Stats=FixStatsNoGdpr({
                        {"cpol-xxx-yyy-cookie-fail_summ", 2},
                        {"cpol-xxx-yyy-cookie-fix-dryRun_summ", 2},
                        {"cpol-xxx-yyy-cookie-skip_summ", 3},
                        {"cpol-xxx-yyy-cookie-total_summ", 5},
                        {"cpol-xxx-yyy-fail_summ", 1},
                        {"cpol-xxx-yyy-fix-dryRun_summ", 1},
                        {"cpol-xxx-yyy-total_summ", 1},
                    }, CookieSimple().size()),
                },
            }));
        }
    }

    Y_UNIT_TEST(TestNoSupportNameRe) {
        // No user-agent should work the same way a not supporting user-agent
        for (auto ua : {TStrVec{}, TStrVec{TString(FirefoxUA)}}) {
            Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
                .In={
                    .Cfg=MakeNameReConfig(true),
                    .UserAgent=ua,
                    .SetCookie=CookieNameRe(),
                },
                .Out={
                    .SetCookie=ToCookie({
                        {.Name="SsUndefined"},
                        {.Name="SsNone"},
                        {.Name="SsNoneSec", .Secure=true},
                        {.Name="SsLax"},
                        {.Name="SsStrict"},
                        {.Name="NoMatchNone"},
                        {.Name="NoMatchLax", .SameSite=ESameSite::Lax},
                    }),
                    .RespLog=" [cpol u:xxx-yyy fail+fix"
                             " SsNone=Fix:1!BadSameSite, SsNoneSec=Fix:1!BadSameSite,"
                             " SsLax=Fix:1!BadSameSite, SsStrict=Fix:1!BadSameSite,"
                             " NoMatchNone=Fix:1!BadSameSite,]",
                    .Stats=FixStatsNoGdpr({
                        {"cpol-xxx-modified-resp_summ", 1},
                        {"cpol-xxx-yyy-cookie-fail_summ", 5},
                        {"cpol-xxx-yyy-cookie-fix_summ", 5},
                        {"cpol-xxx-yyy-cookie-pass_summ", 1},
                        {"cpol-xxx-yyy-cookie-skip_summ", 1},
                        {"cpol-xxx-yyy-cookie-total_summ", 7},
                        {"cpol-xxx-yyy-fail_summ", 1},
                        {"cpol-xxx-yyy-fix_summ", 1},
                        {"cpol-xxx-yyy-total_summ", 1},
                    }, CookieNameRe().size()),
                },
            }));
        }
    }

    Y_UNIT_TEST(TestNoSupportNameReDryRun) {
        // No user-agent should work the same way a not supporting user-agent
        for (auto ua : {TStrVec{}, TStrVec{TString(FirefoxUA)}}) {
            Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
                .In={
                    .Cfg=MakeNameReConfig(false),
                    .UserAgent=ua,
                    .SetCookie=CookieNameRe(),
                },
                .Out={
                    .SetCookie=CookieNameRe(),
                    .RespLog=" [cpol u:xxx-yyy fail+dryRun"
                             " SsNone=Fix:1!BadSameSite, SsNoneSec=Fix:1!BadSameSite, SsLax=Fix:1!BadSameSite,"
                             " SsStrict=Fix:1!BadSameSite,"
                             " NoMatchNone=Fix:1!BadSameSite,]",
                    .Stats=FixStatsNoGdpr({
                        {"cpol-xxx-yyy-cookie-fail_summ", 5},
                        {"cpol-xxx-yyy-cookie-fix-dryRun_summ", 5},
                        {"cpol-xxx-yyy-cookie-pass_summ", 1},
                        {"cpol-xxx-yyy-cookie-skip_summ", 1},
                        {"cpol-xxx-yyy-cookie-total_summ", 7},
                        {"cpol-xxx-yyy-fail_summ", 1},
                        {"cpol-xxx-yyy-fix-dryRun_summ", 1},
                        {"cpol-xxx-yyy-total_summ", 1},
                    }, CookieNameRe().size()),
                },
            }));
        }
    }

    Y_UNIT_TEST(TestSupport) {
        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeSimpleConfig(true),
                .UserAgent={TString(ChromimUA)},
                .SetCookie=CookieSimple(),
            },
            .Out={
                .SetCookie=ToCookie({
                    {.Name="SsUndefined"},
                    {.Name="SsNone", .SameSite=ESameSite::None, .Secure=true},
                    {.Name="SsNoneSec", .SameSite=ESameSite::None, .Secure=true},
                    {.Name="SsLax", .SameSite=ESameSite::Lax},
                    {.Name="SsStrict", .SameSite=ESameSite::Strict}
                }),
                .RespLog=" [cpol u:xxx-yyy fail+fix SsNone=Fix:1!NotSecure,]",
                .Stats=FixStatsNoGdpr({
                    {"cpol-xxx-modified-resp_summ", 1},
                    {"cpol-xxx-yyy-cookie-fail_summ", 1},
                    {"cpol-xxx-yyy-cookie-fix_summ", 1},
                    {"cpol-xxx-yyy-cookie-pass_summ", 1},
                    {"cpol-xxx-yyy-cookie-skip_summ", 3},
                    {"cpol-xxx-yyy-cookie-total_summ", 5},
                    {"cpol-xxx-yyy-fail_summ", 1},
                    {"cpol-xxx-yyy-fix_summ", 1},
                    {"cpol-xxx-yyy-total_summ", 1},
                }, CookieSimple().size()),
            },
        }));
    }

    Y_UNIT_TEST(TestSupportDryRun) {
        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeSimpleConfig(false),
                .UserAgent={TString(ChromimUA)},
                .SetCookie=CookieSimple(),
            },
            .Out={
                .SetCookie=CookieSimple(),
                .RespLog=" [cpol u:xxx-yyy fail+dryRun SsNone=Fix:1!NotSecure,]",
                .Stats=FixStatsNoGdpr({
                    {"cpol-xxx-yyy-cookie-fail_summ", 1},
                    {"cpol-xxx-yyy-cookie-fix-dryRun_summ", 1},
                    {"cpol-xxx-yyy-cookie-skip_summ", 3},
                    {"cpol-xxx-yyy-cookie-pass_summ", 1},
                    {"cpol-xxx-yyy-cookie-total_summ", 5},
                    {"cpol-xxx-yyy-fail_summ", 1},
                    {"cpol-xxx-yyy-fix-dryRun_summ", 1},
                    {"cpol-xxx-yyy-total_summ", 1},
                }, CookieSimple().size()),
            },
        }));
    }

    Y_UNIT_TEST(TestSupportNameRe) {
        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeNameReConfig(true),
                .UserAgent={TString(ChromimUA)},
                .SetCookie=CookieNameRe(),
            },
            .Out={
                .SetCookie=ToCookie({
                    {.Name="SsUndefined", .SameSite=ESameSite::None, .Secure=true},
                    {.Name="SsNone", .SameSite=ESameSite::None, .Secure=true},
                    {.Name="SsNoneSec", .SameSite=ESameSite::None, .Secure=true},
                    {.Name="SsLax", .SameSite=ESameSite::None, .Secure=true},
                    {.Name="SsStrict", .SameSite=ESameSite::None, .Secure=true},
                    {.Name="NoMatchNone", .SameSite=ESameSite::None, .Secure=true},
                    {.Name="NoMatchLax", .SameSite=ESameSite::Lax},
                }),
                .RespLog=" [cpol u:xxx-yyy fail+fix"
                         " SsUndefined=Fix:1!BadSameSite, SsNone=Fix:1!NotSecure,"
                         " SsLax=Fix:1!BadSameSite, SsStrict=Fix:1!BadSameSite,"
                         " NoMatchNone=Fix:1!NotSecure,]",
                .Stats=FixStatsNoGdpr({
                    {"cpol-xxx-modified-resp_summ", 1},
                    {"cpol-xxx-yyy-cookie-fail_summ", 5},
                    {"cpol-xxx-yyy-cookie-fix_summ", 5},
                    {"cpol-xxx-yyy-cookie-pass_summ", 1},
                    {"cpol-xxx-yyy-cookie-skip_summ", 1},
                    {"cpol-xxx-yyy-cookie-total_summ", 7},
                    {"cpol-xxx-yyy-fail_summ", 1},
                    {"cpol-xxx-yyy-fix_summ", 1},
                    {"cpol-xxx-yyy-total_summ", 1},
                }, CookieNameRe().size()),
            },
        }));
    }

    Y_UNIT_TEST(TestSupportNameReDryRun) {
        Y_COOKIE_POLICY_TEST_POLICY((TPolicyTestCase{
            .In={
                .Cfg=MakeNameReConfig(false),
                .UserAgent={TString(ChromimUA)},
                .SetCookie=CookieNameRe(),
            },
            .Out={
                .SetCookie=CookieNameRe(),
                .RespLog=" [cpol u:xxx-yyy fail+dryRun"
                         " SsUndefined=Fix:1!BadSameSite, SsNone=Fix:1!NotSecure,"
                         " SsLax=Fix:1!BadSameSite, SsStrict=Fix:1!BadSameSite,"
                         " NoMatchNone=Fix:1!NotSecure,]",
                .Stats=FixStatsNoGdpr({
                    {"cpol-xxx-yyy-cookie-fail_summ", 5},
                    {"cpol-xxx-yyy-cookie-fix-dryRun_summ", 5},
                    {"cpol-xxx-yyy-cookie-pass_summ", 1},
                    {"cpol-xxx-yyy-cookie-skip_summ", 1},
                    {"cpol-xxx-yyy-cookie-total_summ", 7},
                    {"cpol-xxx-yyy-fail_summ", 1},
                    {"cpol-xxx-yyy-fix-dryRun_summ", 1},
                    {"cpol-xxx-yyy-total_summ", 1},
                }, CookieNameRe().size()),
            },
        }));
    }
}
