#include "server.h"

#include <saas/indexerproxy/unistat_signals/signals.h>

#include <saas/util/queue.h>
namespace {
    class TMonitorReport: public IObjectInQueue {
    private:
        bool IsActive;
        TManualEvent Stopped;
    public:

        TMonitorReport() {
            IsActive = true;
        }

        void Stop() {
            IsActive = false;
            Stopped.Signal();
        }

        void Process(void* /*ThreadSpecificResource*/) override {
            IsActive = true;
            DEBUG_LOG << "--------------------------------ReportOnStop------------------------------" << Endl;
            while (IsActive) {
                auto metric = NDispatchableDocument::GetMetric();
                TStringStream ss;
                ss << "ReportStart: " << Endl;
                ss << "tasks: " << metric.TasksCount << "; docs: " << metric.DocsCount << Endl;
                DEBUG_LOG << ss.Str();
                Stopped.WaitT(TDuration::MilliSeconds(1000));
            }
            DEBUG_LOG << "--------------------------------ReportStopped------------------------------" << Endl;
        }
    };
}

TClientRequest* THttpProxyRTYServer::CreateClient() {
    return new THttpProxyIndexerClient(Executor, FlowMirror);
}

THttpProxyRTYServer::THttpProxyRTYServer(const TProxyConfig& config)
    : Config(config)
    , DeferredMessagesQueue(config.GetDispConfig())
    , Dispatcher(config.GetDispConfig(), DeferredMessagesQueue)
    , Authorizer(config.GetAuthKeyWord())
    , Metrics(&GetGlobalMetrics(), "")
    , Executor(Config, WatchdogSubscriber, Metrics, Destroyer, Dispatcher, Authorizer)
    , Export(config.GetExportConfig(), Executor)
    , FlowMirror(config.GetFlowMirrorConfig())
{
    Server.Reset(new THttpMultiServer(this, config.GetHttpOptionsConfig(), config.GetHttpServerInstances()));

    for (auto&& service : Config.GetServiceMap()) {
        Metrics.AddStaticMetric(service.first);
    }

    FlowMirror.RegisterMetrics(GetGlobalMetrics());

    if (Config.WatchdogOptionsFiles.size()) {
        Watchdog = new TWatchdogOptionsHandle(Config.GetWatchdogOptionsFiles(), TDuration::Seconds(5));
        WatchdogSubscriber.Subscribe(*Watchdog);
        Watchdog->Enable();
    }

    TSaasIndexerProxySignals::BuildSignals(Config.GetServices(), Config.GetServicesConfig());
}

THttpProxyRTYServer::~THttpProxyRTYServer() {
    FlowMirror.UnregisterMetrics(GetGlobalMetrics());
}

void THttpProxyRTYServer::Stop(ui32 /*rigidStopLevel*/, const TCgiParameters* /*cgiParams*/) {
    UnregisterGlobalMessageProcessor(this);
    TThreadPool monitoring("MonitorReport");
    ::TMonitorReport monitor;
    monitoring.Start(1);
    monitoring.SafeAdd(&monitor);
    Export.Stop();
    Server->ShutdownAndWait();
    DeferredMessagesQueue.Stop();
    Executor.Stop();
    Dispatcher.Stop();
    Executor.StopFinishExecutor();
    DeferredMessagesQueue.StopStorage();
    monitor.Stop();
    monitoring.Stop();
}

void THttpProxyRTYServer::Run() {
    INFO_LOG << "Deferred messages queue storage starting..." << Endl;
    DeferredMessagesQueue.StartStorage();
    INFO_LOG << "Deferred messages queue storage starting... OK" << Endl;

    INFO_LOG << "Executor starting..." << Endl;
    Executor.Start(Config.SenderThreads);
    INFO_LOG << "Executor starting... OK" << Endl;

    INFO_LOG << "Deferred messages queue starting..." << Endl;
    DeferredMessagesQueue.Start(Executor);
    INFO_LOG << "Deferred messages queue starting... OK" << Endl;

    INFO_LOG << "HTTP server starting..." << Endl;
    Server->Start();
    INFO_LOG << "HTTP server starting... OK" << Endl;

    Export.Start();
    RegisterGlobalMessageProcessor(this);
}

bool THttpProxyRTYServer::Process(IMessage* message) {
    if (TMessageCollectIndexerProxyInfo* mci = dynamic_cast<TMessageCollectIndexerProxyInfo*>(message)) {
        DeferredMessagesQueue.GetQueuesInfo(mci->QueuesInfo);
        return true;
    }
    return false;
}

TString THttpProxyRTYServer::Name() const {
    return "IndexerProxyServer";
}
