#pragma once

#include "sender.h"

#include <saas/deploy_manager/meta/cluster.h>
#include <saas/deploy_manager/scripts/common/script.h>
#include <saas/deploy_manager/scripts/common/scripts_helper.h>

#include <saas/library/searchmap/searchmap.h>
#include <saas/util/cluster/cluster.h>
#include <saas/util/external/dc.h>
#include <saas/util/json/json.h>
#include <util/system/mutex.h>

namespace NRTYDeploy {

    class TScriptBroadcast: public IScript, public NSearchMapParser::ISearchMapScannerCallback {
    private:
        TMutex Mutex;
        TCondVar CondVar;
        ui32 ActiveRequestsCount = 0;
        TBroadcastSender Requester;
        void PrepareJsonForReply(const TBroadcastSlotData& slot, NJson::TJsonValue& reply);
        NJson::TJsonValue GetSlotControllerStatus(const TBroadcastSlotData& slot, NJson::TJsonValue& reply, const bool updateOnly) const;

    protected:
        NJson::TJsonValue Report;
        TString Service;
        TString ServiceType;
        TString CType;
        NUtil::TJsonFilter Filter;
        TString Command;
        ui32 CodeReply;
        ICommonData* CommonData;
        bool ReplyHasGlobalServerStatus = false;
        bool NeedStatus = true;
        bool WithSd = true;

        virtual void DoPrepareJsonForReply(const TBroadcastSlotData& /*slot*/, NJson::TJsonValue& /*reply*/) {}
        virtual bool MakeReport(IOutputStream& os);
        virtual bool PrepareCustom(IDeployInfoRequest& /*request*/) {
            return true;
        }

    public:

        TScriptBroadcast()
            : Requester(*this)
        {

        }

        static TFactory::TRegistrator<TScriptBroadcast> Registrator;

        const TString& GetCommand() const {
            return Command;
        }

        virtual bool Process(IDeployInfoRequest& request) override;
        virtual bool OnService(const NSearchMapParser::TSearchMapService& info) override;
        virtual void OnHost(const NSearchMapParser::TSearchMapHost& host, const NSearchMapParser::TSearchMapReplica& replica, const NSearchMapParser::TSearchMapService& service) override;
        void RunAsync(TAutoPtr<IObjectInQueue> obj);
        void AddReplyInfo(const TBroadcastSlotData& slot, const TString& reply);
    };

}

