#include "cookie_registry.h"
#include "cookie_type.h"

#include <balancer/kernel/cookie/gdpr/gdpr.cfgproto.pb.h>

#include <library/cpp/resource/resource.h>
#include <library/cpp/proto_config/config.h>

#include <util/generic/is_in.h>
#include <util/stream/str.h>

namespace NGdprCookie {
    namespace {
        template <bool DetectConflicts>
        class TDefaultCookieRegistry : public TCookieRegistry {
        public:
            TDefaultCookieRegistry()
                : TCookieRegistry(([]() {
                    TStringStream rawCfg(NResource::Find("/gdpr-cookies/config.json"));
                    return NProtoConfig::ParseConfigFromJson<TCookies>(rawCfg);
                })(), DetectConflicts)
            {}
        };
    }

    void InitCookieRegistry(bool detectConflicts) {
        if (detectConflicts) {
            Default<TDefaultCookieRegistry<true>>();
        } else {
            Default<TDefaultCookieRegistry<false>>();
        }
    }

    const TCookie& CookieDescr(TStringBuf name) noexcept {
        return Default<TDefaultCookieRegistry<false>>().Get(name);
    }

    ECookieType CookieType(TStringBuf name) noexcept {
        return CookieDescr(name).type();
    }

    bool KeepCookie(ECookieType cookieType, EGdpr gdpr) noexcept {
        switch (cookieType) {
        case ECookieType::Tech:
            return true;
        case ECookieType::Analytic:
            return IsIn({
                EGdpr::KeepAll,
                EGdpr::KeepTechAnalytic
            }, gdpr);
        default:
            return IsIn({
                EGdpr::KeepAll,
                EGdpr::KeepTechOther
            }, gdpr);
        }
    }
}
