#include <balancer/modules/cookie_policy/common/domain_info.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(TDomainInfoTest) {
    struct TDomainInfoTest {
        TStrVec Hosts;
        TStrVec XHttpsRequest;
        TStrVec XYandexHttps;
        bool ConnIsTls = false;
    };

    auto DoTestDomainInfo(const TDomainInfoTest& test) {
        TProcessMock proc;
        TTestConnDescr descr(proc);
        TRequest& req = *descr.ConnDescr().Request;
        for (auto&& h : test.Hosts) {
            req.Headers().Add("host", h);
        }
        for (auto&& h : test.XHttpsRequest) {
            req.Headers().Add("x-https-request", h);
        }
        for (auto&& h : test.XYandexHttps) {
            req.Headers().Add("x-yandex-https", h);
        }
        descr.ConnDescr().Properties->UserConnIsSsl = test.ConnIsTls;
        return GetDomainInfo(descr.ConnDescr());
    }

    Y_UNIT_TEST(TestDomainInfo) {
        UNIT_ASSERT_VALUES_EQUAL(DoTestDomainInfo({}), TDomainInfo());
        UNIT_ASSERT_VALUES_EQUAL(DoTestDomainInfo({.Hosts={"127.0.0.1"}}), (TDomainInfo{}));
        UNIT_ASSERT_VALUES_EQUAL(DoTestDomainInfo({.Hosts={"[64:ff9b::192.0.2.128]"}}), (TDomainInfo{}));
        UNIT_ASSERT_VALUES_EQUAL(DoTestDomainInfo({.Hosts={"localhost"}}), (TDomainInfo{
            .Domain="localhost",
            .DomainWcard="localhost",
        }));
        UNIT_ASSERT_VALUES_EQUAL(DoTestDomainInfo({.Hosts={"yandex.ru"}}), (TDomainInfo{
            .Domain="yandex.ru",
            .DomainRoot="yandex.ru",
            .DomainWcard="yandex.TLD",
        }));
        UNIT_ASSERT_VALUES_EQUAL(DoTestDomainInfo({.Hosts={"yandex.ru."}}), (TDomainInfo{
            .Domain="yandex.ru",
            .DomainRoot="yandex.ru",
            .DomainWcard="yandex.TLD",
        }));
        UNIT_ASSERT_VALUES_EQUAL(DoTestDomainInfo({.Hosts={"WWW.YANDEX.RU", "www.yandex.ru"}}), (TDomainInfo{
            .Domain="www.yandex.ru",
            .DomainRoot="yandex.ru",
            .DomainWcard="www.yandex.TLD",
        }));
        UNIT_ASSERT_VALUES_EQUAL(DoTestDomainInfo({.Hosts={"yandex.com"}}), (TDomainInfo{
            .Domain="yandex.com",
            .DomainRoot="yandex.com",
            .DomainWcard="yandex.TLD",
            .IsGdpr=true,
        }));
        // The case should be disallowed by the http layer.
        UNIT_ASSERT_VALUES_EQUAL(DoTestDomainInfo({.Hosts={"yandex.ru", "yandex.ru."}}), (TDomainInfo{
            .Domain="yandex.ru",
            .DomainRoot="yandex.ru",
            .DomainWcard="yandex.TLD",
        }));
        UNIT_ASSERT_VALUES_EQUAL(DoTestDomainInfo({.ConnIsTls=1}), (TDomainInfo{.IsSecure=true}));
        UNIT_ASSERT_VALUES_EQUAL(DoTestDomainInfo({.XYandexHttps={"yes"}}), (TDomainInfo{.IsSecure=true}));
        UNIT_ASSERT_VALUES_EQUAL(DoTestDomainInfo({.XYandexHttps={"no"}}), (TDomainInfo{}));
        UNIT_ASSERT_VALUES_EQUAL(DoTestDomainInfo({.XYandexHttps={"no", "yes", "no"}}), (TDomainInfo{.IsSecure=true}));
        UNIT_ASSERT_VALUES_EQUAL(DoTestDomainInfo({.XHttpsRequest={"yes"}}), (TDomainInfo{.IsSecure=true}));
        UNIT_ASSERT_VALUES_EQUAL(DoTestDomainInfo({.XHttpsRequest={"no"}}), (TDomainInfo{}));
        UNIT_ASSERT_VALUES_EQUAL(DoTestDomainInfo({.XHttpsRequest={"no", "yes", "no"}}), (TDomainInfo{.IsSecure=true}));
    }
}
