#include <balancer/kernel/http/parser/request_builder.h>

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

using namespace NSrvKernel;

Y_UNIT_TEST_SUITE(TRequestBuilderTest) {
    Y_UNIT_TEST(SmokingTest) {
        TRequest response = BuildRequest().Version11()
                                          .Method(EMethod::GET)
                                          .Path("/foo");
        UNIT_ASSERT_EQUAL(1, response.RequestLine().MajorVersion);
        UNIT_ASSERT_EQUAL(1, response.RequestLine().MinorVersion);
        UNIT_ASSERT_EQUAL(EMethod::GET, response.RequestLine().Method);
        UNIT_ASSERT_EQUAL("/foo", response.RequestLine().Path.AsStringBuf());
    }

    Y_UNIT_TEST(ImplicitReasonStringTest) {
        for (auto method : {EMethod::PUT, EMethod::POST, EMethod::HEAD}) {
            TRequest response = BuildRequest().Version10()
                                              .Method(method)
                                              .Path("/boo");
            UNIT_ASSERT_EQUAL(1, response.RequestLine().MajorVersion);
            UNIT_ASSERT_EQUAL(0, response.RequestLine().MinorVersion);
            UNIT_ASSERT_EQUAL(method, response.RequestLine().Method);
        }
    }

    Y_UNIT_TEST(HeaderTest) {
        TVector<std::pair<TString, TString>> headers = {{"abc", "def"},
                                                        {"123", "456"}};
        TRequest response = BuildRequest().Version11()
                                          .Method(EMethod::TRACE)
                                          .Path("/goo")
                                          .Header(headers[0].first, headers[0].second)
                                          .Header(headers[1].first, headers[1].second);
        for (const auto& [key, value] : headers) {
            auto header = response.Headers().FindValues(key);
            UNIT_ASSERT_EQUAL(key, header->first);
            UNIT_ASSERT_EQUAL(value, header->second[0]);

            auto values = response.Headers().GetValuesRef(key);
            auto constValueBrackets = std::as_const(response.Headers()).GetValuesRef(key);
            UNIT_ASSERT_EQUAL(value, values[0]);
            UNIT_ASSERT_EQUAL(value, constValueBrackets[0]);
        }
    }

    void UriTest(TStringBuf full, TStringBuf path, TStringBuf cgi) {
        TRequest response = BuildRequest().Version11()
                                          .Method(EMethod::GET)
                                          .Uri(full);
        UNIT_ASSERT_EQUAL(1, response.RequestLine().MajorVersion);
        UNIT_ASSERT_EQUAL(1, response.RequestLine().MinorVersion);
        UNIT_ASSERT_EQUAL(EMethod::GET, response.RequestLine().Method);
        UNIT_ASSERT_EQUAL(path, response.RequestLine().Path.AsStringBuf());
        UNIT_ASSERT_EQUAL(cgi, response.RequestLine().CGI.AsStringBuf());
    }

    Y_UNIT_TEST(UriTest) {
        UriTest("/foo", "/foo", "");
        UriTest("/foo?abc=qed&def=abc", "/foo", "?abc=qed&def=abc");
        UriTest("/foo?abc=qed?&def=abc", "/foo", "?abc=qed?&def=abc");
    }
}
