#include "module.h"

#include "handler.h"

#include <balancer/kernel/log/errorlog.h>
#include <balancer/kernel/matcher/matcher.h>
#include <balancer/kernel/module/iface.h>
#include <balancer/kernel/module/module.h>
#include <balancer/kernel/srcrwr/srcrwr_helper.h>

using namespace NSrvKernel;

namespace NModSrcrwr {

MODULE(srcrwr) {
public:
    explicit TModule(const TModuleParams& mp)
        : TModuleBase(mp)
        , Handler_(MakeHolder<NSrcrwr::THelper>())
    {
        Config->ForEach(this);
    }

private:
    START_PARSE
    {
        ON_KEY("id", Id_) {
            return;
        }

        if (auto matcher = ConstructRequestMatcher(Control, key, value->AsSubConfig())) {
            Y_ENSURE_EX(!Matcher_, TConfigParseError() << "several matchers");
            Matcher_ = std::move(matcher);
            return;
        }

        {
            Y_ENSURE_EX(!Submodule_, TConfigParseError() << "several modules");
            Submodule_ = Loader->MustLoad(key, Copy(value->AsSubConfig()));
            return;
        }
    } END_PARSE

    TError DoRun(const TConnDescr& descr) const override
    {
        try {
            if (Matcher_->Match(descr) && Handler_.Handle(descr, Id_)) {
                LOG_ERROR(TLOG_DEBUG, descr, "set srcrwr handling set for " << Id_);
            }
        } catch(std::exception& e) {
            LOG_ERROR(TLOG_ERR, descr, "exception in srcrwr module: " << e.what());
        } catch(...) {
            LOG_ERROR(TLOG_ERR, descr, "exception in srcrwr module");
        }

        Y_DEFER {
            Handler_.CleanUp(descr);
        };

        auto result = Submodule_->Run(descr);

        return result;
    }

private:
    THolder<IModule> Submodule_;

    TString Id_;
    THolder<IRequestMatcher> Matcher_;

    THandler Handler_;
};

}

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