#pragma once

#include "abstract_processor.h"

#include <saas/library/daemon_base/module/module.h>
#include <saas/rtyserver/config/config.h>

#include <library/cpp/mediator/messenger.h>

#include <util/generic/maybe.h>

#define SYNCHRONIZER_MODULE_NAME "Synchronizer"

namespace NRTYServer {
    class TSynchronizerConfig;

    class TSynchronizer: public IDaemonModule, public IMessageProcessor {
    private:
        const IServerConfig& Config;
        const TSynchronizerConfig* SynchronizerConfig;
        static TDaemonModules::TFactory::TRegistrator<TSynchronizer> Registrator;
        TVector<ISynchronizerProcessor::TPtr> Processors;

    public:

        static bool IsUsedStatic(const IServerConfig& config) {
            return config.GetModulesSet().contains(SYNCHRONIZER_MODULE_NAME);
        }

        TSynchronizer(const IServerConfig& config);

        ~TSynchronizer() override {}
        bool Start(const TStartContext& startContext) override;
        bool Stop(const TStopContext& stopContext) override;

        TString Name() const override {
            return SYNCHRONIZER_MODULE_NAME;
        }

        const TSynchronizerConfig* GetConfig() const {
            return SynchronizerConfig;
        }

        const TRTYServerConfig& GetRTYConfig() const {
            return Config.GetMeAs<TRTYServerConfig>();
        }

        bool Process(IMessage* message) override;
    };

    class TMessageSynchronizerCall : public IMessage{
    private:
        NJson::TJsonValue Info;
        TString Error;

        const TCgiParameters& Cgi;
        const TStringBuf PostBuffer;
        TAsyncTaskExecutor::TTask& Task;

    public:
        TMaybeFail<bool> Correctness;

        TMessageSynchronizerCall(const TCgiParameters& cgi, TStringBuf postBuffer, TAsyncTaskExecutor::TTask& task)
            : Cgi(cgi)
            , PostBuffer(postBuffer)
            , Task(task)
        {
        }

        const NJson::TJsonValue& GetInfo() const {
            return Info;
        }

        NJson::TJsonValue& GetInfo() {
            return Info;
        }

        const TString& GetError() const {
            return Error;
        }

        void SetError(const TString& error) {
            Error = error;
        }

        TAsyncTaskExecutor::TTask& GetTask() {
            return Task;
        }

        const TCgiParameters& GetCgi() const {
            return Cgi;
        }

        TStringBuf GetPostBuffer() const {
            return PostBuffer;
        }
    };
}
