#include "config_tab_worker.h"
#include <library/cpp/yconf/patcher/unstrict_config.h>
#include <library/cpp/logger/global/global.h>
#include <util/folder/path.h>

namespace NRTYDeploy {
    using namespace NDMInterface;
    class TConfigTabWorkerQueryLanguage : public TConfigTabWorker {
    public:
        void FillTabImpl(NDMInterface::TConfigTab& tab, IVersionedStorage& storage, const NDMInterface::TProjectConfig::TComponent* component, const NDMInterface::TProjectConfig& /*projectConfig*/) const override {
            tab.SetRequired(false);
            tab.SetType(NDMInterface::TConfigTab::RTYSERVER_QUERY_LANGUAGE);
            tab.SetTabName("QueryLanguage");
            tab.SetFilePath("/configs/" + component->GetComponent().GetServiceName() + "/query-language");
            AddField(tab, "*", "");
            tab.SetEnabled(false);
            for (const auto& file : component->GetFiles().GetFile()) {
                if (TFsPath(file.GetPath()).GetName().StartsWith("query-language")) {
                    TString data;
                    if (!storage.GetValue(file.GetPath(), data, file.GetVersion()))
                        ythrow yexception() << "cannot get data from " << file.GetPath() << ", version " << file.GetVersion();
                    TUnstrictConfig ql;
                    if (ql.ParseMemory(data.data())) {
                        tab.SetEnabled(true);
                        tab.SetFilePath(file.GetPath());
                        for (const auto& dir : ql.GetFirstChild("QueryLanguage")->GetDirectives())
                            AddField(tab, dir.first, dir.second);
                    }
                    break;
                }
            }
        }

        void SetChangedConfigImpl(const NDMInterface::TConfigTab& tab, IVersionedStorage& storage) override {
            TUnstrictConfig cfg;
            VERIFY_WITH_LOG(cfg.ParseMemory(""), "cannot parse empty config");
            for (const auto& field : tab.GetFields())
                cfg.PatchEntry(field.GetName(), field.GetValue());
            if (!storage.SetValue(tab.GetFilePath(), cfg.ToString()))
                ythrow yexception() << "cannot write " << tab.GetFilePath();
        }

        static TFactory::TRegistrator<TConfigTabWorkerQueryLanguage> Registrator;

    private:
        void AddField(NDMInterface::TConfigTab& tab, const TString& name, const TString& value) const {
            NDMInterface::TConfigField& field = *tab.AddFields();
            SetFieldName(field, "QueryLanguage." + name);
            field.SetDefaultState(NDMInterface::TConfigField::NO_DEFAULT);
            field.SetType(NDMInterface::TConfigField::QUERY_LANGUAGE);
            SetFieldValue(field, value);
        }
    };

    TConfigTabWorkerQueryLanguage::TFactory::TRegistrator<TConfigTabWorkerQueryLanguage> TConfigTabWorkerQueryLanguage::Registrator(TConfigTab::RTYSERVER_QUERY_LANGUAGE);
}
