#pragma once

#include "mem_watcher.h"
#include "request.h"
#include <saas/deploy_manager/config/config.h>
#include <saas/deploy_manager/modules/resources/resources.h>
#include <saas/deploy_manager/modules/service_discovery/sd_module.h>
#include <saas/deploy_manager/server/client/client.h>
#include <saas/deploy_manager/server/messages/collect_dm_info.h>
#include <saas/deploy_manager/storage/impl/controllers_checker.h>
#include <saas/deploy_manager/storage/impl/zoo_queue.h>
#include <saas/library/daemon_base/daemon/messages.h>
#include <saas/library/daemon_base/daemon/controller.h>
#include <saas/util/cluster/cluster.h>
#include <saas/util/external/mail_service.h>
#include <saas/util/queue.h>

#include <library/cpp/http/server/http.h>
#include <util/system/event.h>

class THttpDeployManager: public THttpServer::ICallBack, public NRTYDeploy::ICommonData, public IServer {
private:
    NRTY::TMailService MailService;
    THolder<THttpServer> Server;
    const TDeployManagerConfig& Config;
    THolder<NRTYDeploy::IVersionedStorage> Storage;
    THolder<NRTYDeploy::IDistrTasksQueue> Queue;
    THolder<NRTYDeployServer::TWatchDog> WatchDog;
    THolder<TNannyModule> NannyModule;
    THolder<TRequestWizardModule> RequestWizardModule;
    THolder<TServices20Module> Services20Module;
    THolder<TJugglerModule> JugglerModule;
    THolder<TGolovanModule> GolovanModule;
    THolder<NRTYDeploy::TCacheModule> CacheModule;
    THolder<TSDModule> SDModule;

    TRTYMtpQueue Executor;
    TRTYMtpQueue ExecutorRegular;
    TThreadPool ScriptsServiceQueue;
    THolder<NRTYDeploy::TResourcesManager> Resources;
    THolder<NRTYDeploy::TControllersChecker> ControllersChecker;
    TManualEvent Active;
    TManualEvent ActiveRegular;
public:

    typedef TDeployManagerConfig TConfig;
    typedef NRTYDeploy::TMessageCollectDeployManagerInfo TInfoCollector;

    THttpDeployManager(const TDeployManagerConfig& config);
    virtual ~THttpDeployManager();

    virtual const NRTYDeploy::TResourcesManager& GetResourcesManager() const override {
        return *Resources;
    }

    NRTYDeploy::TResourcesManager& GetResourcesManager() {
        return *Resources;
    }

    virtual const TDeployManagerConfig& GetConfig() const override {
        return Config;
    }

    virtual TClientRequest* CreateClient() override {
        return new TDeployInfoRequest(this, Config);
    }

    void Run() override;

    virtual NRTYDeploy::IVersionedStorage& GetStorage() override {
        return *Storage;
    }

    virtual const NRTYDeploy::IVersionedStorage& GetStorage() const override {
        return *Storage;
    }

    virtual TNannyModule& GetNannyModule() const override {
        return *NannyModule;
    }

    virtual TSDModule& GetSDModule() const override {
        return *SDModule;
    }

    virtual TJugglerModule& GetJugglerModule() const override {
        return *JugglerModule;
    }

    virtual TGolovanModule& GetGolovanModule() const override {
        return *GolovanModule;
    }

    virtual NRTYDeploy::IDistrTasksQueue& GetQueue() override {
        return *Queue;
    }

    virtual NRTYDeploy::IControllersChecker& GetControllersChecker() override {
        return *ControllersChecker;
    }

    virtual const TString& GetDeployManagerBalanserHost() const override {
        return Config.GetDeployManagerBalanser().Host;
    }

    virtual ui16 GetDeployManagerBalanserPort() const override {
        return Config.GetDeployManagerBalanser().Port;
    }

    virtual const TString& GetDeployManagerBalanserUriPrefix() const override {
        return Config.GetDeployManagerBalanser().UriPrefix;
    }

    virtual TRequestWizardModule& GetRequestWizardModule() override {
        return *RequestWizardModule;
    }

    virtual TServices20Module& GetServices20Module() override {
        return *Services20Module;
    }

    virtual NRTYDeploy::TCacheModule& GetCacheModule() override {
        return *CacheModule;
    }

    virtual void SafeAddAndOwn(TAutoPtr<IObjectInQueue> obj) override {
        ScriptsServiceQueue.SafeAddAndOwn(obj);
    }

    void Stop(ui32 rigidStopLevel = 0, const TCgiParameters* cgiParams = nullptr) override;
};
