#pragma once

#include "cookie_policy.h"
#include "controls_reader.h"
#include "domain_info.h"
#include "gdpr_controls.h"
#include "gdpr.h"
#include "mode_controls.h"
#include "parse_render.h"

namespace NModCookiePolicy {
    struct TCombinedPolicy : TMoveOnly {
        TModuleConfig Config;
        TDeque<TPolicyHolder> Policies;
        TModeControls ModeControls;
        TGdprControls GdprControls;
        TString ParserUuid;
    };


    struct TCombinedPolicyCtx : TMoveOnly {
        TDomainInfo DomainInfo;
        TDeque<TPolicyCtx> Contexts;
        TVector<TRequestCookie> Cookies;
        TExtractedIsGdpr IsGdprCookie;
        TMaybe<EIsGdpr> IsGdprUpdate;
        TExtractedIsGdprB IsGdprBCookie;
        TMaybe<TIsGdprB> IsGdprBUpdate;
    };


    class TCombinedPolicyTls : TNonCopyable {
    public:
        explicit TCombinedPolicyTls(const TCombinedPolicy& pol, TSharedStatsManager& manager);
        explicit TCombinedPolicyTls(const TCombinedPolicyTls& tmpl, IWorkerCtl& ctl);

        explicit operator bool() const noexcept {
            return !Policies_.empty();
        }

        const TCombinedPolicy& Policy() const noexcept {
            return Policy_;
        }

        void SetModeControls(const TModeControls* controls) noexcept {
            ModeControls_ = controls;
        }

        void SetGdprControls(const TGdprControls* controls) noexcept {
            GdprControls_ = controls;
        }

        TMaybe<TCombinedPolicyCtx> ApplyToRequest(const TConnDescr& descr) noexcept;

        [[nodiscard]]
        TString /*responseLog*/ ApplyToResponse(
            TCombinedPolicyCtx& ctx, const TConnDescr& descr, TResponse& resp) noexcept;

    private:
        const TCombinedPolicy& Policy_;
        TGlobalStats Stats_;
        TDeque<TPolicyTls> Policies_;
        const TModeControls* ModeControls_ = nullptr;
        const TGdprControls* GdprControls_ = nullptr;
    };
}
