#include <balancer/modules/cookie_policy/common/controls_reader.h>
#include <balancer/modules/cookie_policy/common/cookie_policy.cfgproto.pb.h>
#include <balancer/modules/cookie_policy/common/mode_controls.h>
#include <balancer/modules/cookie_policy/ut_common/utils.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(TModeControlsTest) {
    Y_UNIT_TEST(TestBadParse) {
        TProcessMock proc;
        TTestConnDescr descr(proc);
        auto ctl = ParseControls<TModeControls, TModeControlsCfg>(
            "x x x", "controls", "cookie_policy", descr.ConnDescr()
        );
        UNIT_ASSERT(!ctl);
    }

    void DoTestParse(TString data) {
        TProcessMock proc;
        TTestConnDescr descr(proc);
        auto ctl = ParseControls<TModeControls, TModeControlsCfg>(data, "controls", "cookie_policy", descr.ConnDescr());

        UNIT_ASSERT(ctl);

        UNIT_ASSERT_VALUES_EQUAL(ctl->ParserMode(TDomainInfo{.Domain="ccc"}), EPolicyMode::Fix);
        UNIT_ASSERT(!ctl->ParserMode(TDomainInfo{.Domain="ddd"}));
        UNIT_ASSERT_VALUES_EQUAL(ctl->ParserMode(TDomainInfo{.Domain="eee"}), EPolicyMode::DryRun);

        UNIT_ASSERT_VALUES_EQUAL(ctl->PolicyMode("ppp", TDomainInfo{.Domain="fff"}), EPolicyMode::Fix);
        UNIT_ASSERT(!ctl->PolicyMode("ppp", TDomainInfo{.Domain="ggg"}));
        UNIT_ASSERT_VALUES_EQUAL(ctl->PolicyMode("ppp", TDomainInfo{.Domain="eee"}), EPolicyMode::DryRun);
    }

    Y_UNIT_TEST(TestParseLua) {
        DoTestParse(R"=({
    policy_modes = {
        ppp = {
            mode = "dry_run";
            unknown_field_tolerance = "xxx";
            domain_modes = {
                {
                    mode = "fix";
                    unknown_field_tolerance = "xxx";
                    domain_filter = {
                        unknown_field_tolerance = "xxx";
                        include_domains_re = "fff";
                    };
                };
                {
                    domain_filter = {
                        include_domains_re = "ggg";
                    };
                };
            };
        };
    };
    unknown_field_tolerance = "xxx";
    parser_mode = {
        mode = "dry_run";
        domain_modes = {
            {
                mode = "fix";
                domain_filter = {
                    include_domains_re = "ccc";
                };
            };
            {
                domain_filter = {
                    include_domains_re = "ddd";
                };
            };
        };
    };
};)=");
    }

    Y_UNIT_TEST(TestParseJson) {
        DoTestParse(R"=({
    "policy_modes": {
        "ppp": {
            "mode": "dry_run",
            "unknown_field_tolerance": "xxx",
            "domain_modes": [
                {
                    "mode": "fix",
                    "unknown_field_tolerance": "xxx",
                    "domain_filter": {
                        "unknown_field_tolerance": "xxx",
                        "include_domains_re": "fff"
                    }
                },
                {
                    "domain_filter": {
                        "include_domains_re": "ggg"
                    }
                }
            ]
        }
    },
    "unknown_field_tolerance": "xxx",
    "parser_mode": {
        "mode": "dry_run",
        "domain_modes": [
            {
                "mode": "fix",
                "domain_filter": {
                    "include_domains_re": "ccc"
                }
            },
            {
                "domain_filter": {
                    "include_domains_re": "ddd"
                }
            }
        ]
    }
})=");
    }

    void DoTestParserOff(TString data) {
        TProcessMock proc;
        TTestConnDescr descr(proc);
        auto ctl = ParseControls<TModeControls, TModeControlsCfg>(data, "controls", "cookie_policy", descr.ConnDescr());

        UNIT_ASSERT(ctl);
        UNIT_ASSERT_VALUES_EQUAL(ctl->ParserMode(TDomainInfo{.Domain="ccc"}), EPolicyMode::Off);
        UNIT_ASSERT_VALUES_EQUAL(ctl->ParserMode(TDomainInfo{}), EPolicyMode::Off);
    }

    Y_UNIT_TEST(TestParserOff) {
        DoTestParserOff("{parser_mode={mode=\"off\"}}");
        DoTestParserOff("{\"parser_mode\":{\"mode\":\"off\"}}");
    }
}
