#include "p_global_scope.h"

#include <balancer/kernel/cookie/domain/domain.h>

namespace NModCookiePolicy {
    TPolicyGlobalScope::TPolicyGlobalScope(TString name, const TPolicyGlobalScopeCfg& cfg)
        : TNameMatchPolicyBase(name, cfg, false)
        , Cfg_(cfg)
    {}

    bool TPolicyGlobalScope::MatchRequest(const TPolicyArgs& args) const noexcept {
        return !!args.DomainInfo.DomainRoot;
    }

    TMaybe<ICookiePolicy::TAction> TPolicyGlobalScope::ApplyToResponseCookie(
        TResponseCookieView c, const TPolicyArgs& args) const noexcept
    {
        const auto& cc = c.Const();
        TAction errs;
        const auto dotlessDomain = NCookie::SkipDot(cc.Domain);
        if (!cc.Domain.empty() && !ValidDomainName(dotlessDomain)) {
            errs.Reasons.Set(EResponseCookieReason::BadDomain);
        } else if (dotlessDomain != *args.DomainInfo.DomainRoot) {
            if (!dotlessDomain || dotlessDomain.EndsWith(*args.DomainInfo.DomainRoot)) {
                errs.Reasons.Set(EResponseCookieReason::NotGlobalScope);
            } else {
                errs.Reasons.Set(EResponseCookieReason::WrongDomain);
            }
        }

        if (cc.Path != "/"sv) {
            errs.Reasons.Set(EResponseCookieReason::NotGlobalScope);
        }

        if (errs.Reasons) {
            if (!args.DryRun) {
                auto& mc = c.Mutable();
                mc.Domain.assign(TStringBuf(".")).append(*args.DomainInfo.DomainRoot);
                mc.Path = TStringBuf("/");
            }
            return errs;
        }

        return Nothing();
    }
}
