#include "synchronizer.h"
#include "config.h"

#include "detach_processor.h"
#include "shards_processor.h"
#include "slot_info_processor.h"
#include "sync_processor.h"

#include <saas/rtyserver/common/message_collect_server_info.h>
#include <saas/rtyserver/common/search_control.h>
#include <saas/library/sharding/sharding.h>
#include <saas/util/json/json.h>

namespace NRTYServer {

    bool TSynchronizer::Process(IMessage* message) {
        TMessageSynchronizerCall* syncMessage = dynamic_cast<TMessageSynchronizerCall*>(message);
        TString id;
        if (syncMessage) {
            TString action = syncMessage->GetCgi().Get("action");
            for (auto& p: Processors) {
                DEBUG_LOG << "SYNCHRONIZER: Check processor name: " << p->GetProcessorName() << " == " << action << Endl;
                if (p->GetProcessorName() == action) {
                    syncMessage->Correctness = p->ProcessRequest(syncMessage->GetCgi(), syncMessage->GetPostBuffer(), syncMessage->GetTask());
                    return true;
                }
            }
            syncMessage->Correctness = false;
            syncMessage->GetInfo()["error"] = "Incorrect command";
            return true;
        }
        TMessageCollectServerInfo* messInfo = dynamic_cast<TMessageCollectServerInfo*>(message);
        if (messInfo) {
            bool result = false;
            for (auto& p : Processors) {
                result = result || p->CollectServerInfo(messInfo);
            }
            return result;
        }
        return false;
    }

    bool TSynchronizer::Start(const TStartContext& /*startContext*/) {
        for (auto &p : Processors) {
            p->Start();
        }
        RegisterGlobalMessageProcessor(this);
        return true;
    }

    bool TSynchronizer::Stop(const TStopContext& /*stopContext*/) {
        UnregisterGlobalMessageProcessor(this);
        for (auto &p : Processors) {
            p->Stop();
        }
        return true;
    }

    TSynchronizer::TSynchronizer(const IServerConfig& config)
        : Config(config)
    {
        SynchronizerConfig = Config.GetModuleConfig<TSynchronizerConfig>(SYNCHRONIZER_MODULE_NAME);
        VERIFY_WITH_LOG(SynchronizerConfig, "Module configuration is absent");
        TFsPath(SynchronizerConfig->DetachPath).MkDirs();
        Processors.push_back(new TDetachProcessor(this));
        Processors.push_back(new TSyncProcessor(this));
        Processors.push_back(new TShardsProcessor(this));
        Processors.push_back(new TSlotInfoProcessor(this));
    }

    TDaemonModules::TFactory::TRegistrator<TSynchronizer> TSynchronizer::Registrator(SYNCHRONIZER_MODULE_NAME);
}
