#include "fuzz_common.h"

#include <balancer/modules/cookie_policy/policies/policy_traits.h>

#include <balancer/kernel/testing/conn_descr.h>
#include <balancer/kernel/testing/process_mock.h>
#include <balancer/kernel/testing/stats.h>


namespace NModCookiePolicy {

    TModMock BuildModMock(const TModuleConfig& cfg) {
        TModMock res;
        res.Policy = MakeHolder<TCombinedPolicy>(InitCombinedPolicy(cfg));
        res.Stats = MakeHolder<TStatsFixture>();
        res.TlsTemplate = MakeHolder<TCombinedPolicyTls>(*res.Policy, res.Stats->Manager());
        res.Stats->FreezeAndInit();
        res.Proc = MakeHolder<NSrvKernel::NTesting::TProcessMock>();
        res.Tls = MakeHolder<TCombinedPolicyTls>(*res.TlsTemplate, *res.Proc);
        return res;
    }

    void RunFuzzTest(const TModMock& mock, const TCPTestInput& c) {
        TTestConnDescr descr(*mock.Proc);
        descr.ConnDescr().Properties->Parent.GdprCache = c.GeoCache;
        descr.ConnDescr().Properties->Start = c.Now;
        descr.ConnDescr().Request->RequestLine().Path = TStringStorage(c.Path);

        TStringBuilder reqLog;

        for (auto&& h : c.Host) {
            // While multiple host headers are guaranteed to not happen, they still should not cause a crash.
            descr.ConnDescr().Request->Headers().Add("host", h);
        }
        for (auto&& h : c.Cookie) {
            descr.ConnDescr().Request->Headers().Add("cookie", std::move(h));
        }
        for (auto&& h : c.UserAgent) {
            descr.ConnDescr().Request->Headers().Add("user-agent", h);
        }
        for (auto&& h : c.XYandexEURequest) {
            descr.ConnDescr().Request->Headers().Add("x-yandex-eu-request", h);
        }
        for (auto&& h : c.XIpProperties) {
            descr.ConnDescr().Request->Headers().Add("x-ip-properties", h);
        }

        TResponse resp;
        for (auto&& h : c.SetCookie) {
            resp.Headers().Add("set-cookie", h);
        }

        if (auto ctx = mock.Tls->ApplyToRequest(descr.ConnDescr())) {
            Y_UNUSED(mock.Tls->ApplyToResponse(*ctx, descr.ConnDescr(), resp));
        }
    }
}
