#include <balancer/serval/contrib/cone/mun.h>

#include <balancer/serval/core/buffer.h>
#include <balancer/serval/core/config.h>
#include <balancer/serval/core/http.h>
#include <balancer/serval/core/io.h>
#include <balancer/serval/core/storage.h>

#include <balancer/serval/mod/path_rewrite/path_rewrite.ev.pb.h>

#include <util/stream/output.h>

namespace NSv::NGrpc {
    static const TStringBuf NAME = "path_rewrite";

    static NSv::TAction PathRewrite(const YAML::Node& node, NSv::TAuxData&) {
        THashMap<TString, TString> rewrites;

        for (auto ptr = node[NAME].begin(); ptr != node[NAME].end(); ++ptr) {
            TString from = NSv::Required<TString>(ptr->first);
            TString to = NSv::Required<TString>(ptr->second);
            if (rewrites.count(from)) {
                FAIL_NODE(node, TStringBuilder{} << "duplicate rewrite of path " << from << " is bad!");
            }
            rewrites[from] = to;
        }

        return [rewrites = std::move(rewrites)] (NSv::IStreamPtr& req) {
            THead* rqh = req->Head();
            if (!rqh) {
                return false;
            }
            auto entry = rewrites.find(rqh->PathWithQuery);
            if (entry != rewrites.end()) {
                req->Log().Push<NSv::NEv::TRewriteApplied>(entry->first, entry->second);
                rqh->PathWithQuery = entry->second;
            } else {
                req->Log().Push<NSv::NEv::TRewriteNotApplied>();
            }
            return true;
        };
    }

    SV_DEFINE_ACTION(NAME, PathRewrite);
}
