#include "module.h"

#include <balancer/kernel/module/module.h>
#include <balancer/kernel/rpslimiter/quota_manager.h>

using namespace NSrvKernel;
using namespace NRpsLimiter;

MODULE_BASE(rpslimiter_instance, TModuleWithSubModule) {
private:
    class TRemoteConfigParser : public NConfig::IConfig::IFunc {
    public:
        TRemoteConfigParser(TQuotaManager& manager, TModule* module)
            : QuotaManager_(manager)
            , Module_(module)
        {}

        void DoConsume(const TString& key, NConfig::IConfig::IValue* value) override {
            // Already parsed
            if (IsIn({"local_host_id", "sync_path", "sync_interval"}, key)) {
                return;
            }
            QuotaManager_.Remote[key] = TSubLoader(Module_->Copy(value->AsSubConfig()));
        }

        TQuotaManager& QuotaManager_;
        TModule* Module_;
    };

    class TConfigParser : public NConfig::IConfig::IFunc {
    public:
        TConfigParser(TQuotaManager& manager, TModule* module)
            : QuotaManager_(manager)
            , Module_(module)
        {}

        START_PARSE
            // Already parsed
            if (key == "quotas") {
                return;
            }

            if (key == "remote") {
                TRemoteConfigParser parser(QuotaManager_, Module_);
                value->AsSubConfig()->ForEach(&parser);
                return;
            }

            if (key == "module") {
                TSubLoader(Module_->Copy(value->AsSubConfig())).Swap(Module_->Submodule_);
                return;
            }
        END_PARSE

        TQuotaManager& QuotaManager_;
        TModule* Module_ = nullptr;
    };

public:
    TModule(const TModuleParams& mp)
        : TModuleBase(mp)
        , QuotaManager_(*mp.Control->GetQuotaManager())
    {
        Y_ENSURE_EX(mp.Control->GetQuotaManager(),
            TConfigParseError() << "rpslimiter_instance must be the top level module");

        TConfigParser parser(QuotaManager_, this);
        Config->ForEach(&parser);
    }

private:
    TError DoRun(const TConnDescr& descr) const noexcept override {
        return Submodule_->Run(descr);
    }

    bool DoCanWorkWithoutHTTP() const noexcept override {
        return true;
    }

private:
    TQuotaManager& QuotaManager_;
};

IModuleHandle* NModRpsLimiterInstance::Handle() {
    return TModule::Handle();
}
