#include <saas/common_proxy/lib/saas_action/saas_action.h>
#include <kernel/common_proxy/common/converter.h>
#include <library/cpp/json/json_reader.h>

namespace NCommonProxy {
    namespace {
        class TConfig : public TProcessorConfig {
        public:
            TConfig(const TString& type)
                : TProcessorConfig(type)
            {}

        protected:
            virtual bool DoCheck() const override {
                return true;
            }
        };
    }

    class TSaasActionToProto : public TConverter {
    public:
        TSaasActionToProto(const TString& name, const TProcessorsConfigs& configs)
            : TConverter(name, configs)
        {}

        virtual const TMetaData& GetInputMetaData() const override {
            return Default<TSaasActionMeta>();
        }

        virtual const TMetaData& GetOutputMetaData() const override {
            return Default<TSaasProtoMessageMeta>();
        }
        static TProcessor::TFactory::TRegistrator<TSaasActionToProto> Registrar;
        static TProcessorConfig::TFactory::TRegistrator<TConfig> RegistrarConfig;

    protected:
        virtual bool Convert(TDataSet::TPtr input, TDataSet::TPtr& output, IReplier::TPtr /*replier*/) const override {
            auto doc = input->GetObject<TSaasAction>(TSaasActionMeta::FieldName);
            if (!doc)
                return false;
            auto proto = MakeIntrusive<TSaasProtoMessage>((*doc)->ToProtobuf());
            output = MakeIntrusive<TDataSet>(GetOutputMetaData());
            output->SetObject<TSaasProtoMessage>(TSaasProtoMessageMeta::FieldName, proto);
            return true;
        }
    };

    const TString SAAS_ACTION_TO_PROTO = "SAAS_ACTION_TO_PROTO";
    TProcessor::TFactory::TRegistrator<TSaasActionToProto> TSaasActionToProto::Registrar(SAAS_ACTION_TO_PROTO);
    TProcessorConfig::TFactory::TRegistrator<TConfig> TSaasActionToProto::RegistrarConfig(SAAS_ACTION_TO_PROTO);

    class TJsonToSaasAction : public TConverter {
    public:

        class TInputMeta : public TMetaData {
        public:
            TInputMeta() {
                Register("post",  dtSTRING);
            }
        };

        TJsonToSaasAction(const TString& name, const TProcessorsConfigs& configs)
            : TConverter(name, configs)
        {}

        virtual const TMetaData& GetInputMetaData() const override {
            return Default<TInputMeta>();
        }

        virtual const TMetaData& GetOutputMetaData() const override {
            return Default<TSaasActionMeta>();
        }
        static TProcessor::TFactory::TRegistrator<TJsonToSaasAction> Registrar;
        static TProcessorConfig::TFactory::TRegistrator<TConfig> RegistrarConfig;

    protected:
        virtual bool Convert(TDataSet::TPtr input, TDataSet::TPtr& output, IReplier::TPtr /*replier*/) const override {
            const TString& post = input->Get<TString>("post");
            TStringInput si(post);
            NJson::TJsonValue json = NJson::ReadJsonTree(&si);
            auto doc = MakeIntrusive<TSaasAction>();
            (*doc)->ParseFromJson(json);
            output = MakeIntrusive<TDataSet>(GetOutputMetaData());
            output->SetObject<TSaasAction>(TSaasActionMeta::FieldName, doc);
            return true;
        }
    };

    const TString JSON_TO_SAAS_ACTION = "JSON_TO_SAAS_ACTION";
    TProcessor::TFactory::TRegistrator<TJsonToSaasAction> TJsonToSaasAction::Registrar(JSON_TO_SAAS_ACTION);
    TProcessorConfig::TFactory::TRegistrator<TConfig> TJsonToSaasAction::RegistrarConfig(JSON_TO_SAAS_ACTION);
}
