#pragma once

#include <saas/library/daemon_base/controller_actions/async_controller_action.h>
#include <saas/util/tasks_graph/script.h>
#include <saas/rtyserver/synchronizer/library/sync.h>

#define SYNC_DOWNLOAD_ACTION_NAME "SYNC_DOWNLOAD"

namespace NDaemonController {

    class TDownloadAction : public TControllerAsyncAction {
    private:
        TString IdRes;
        TMaybe<NRTYServer::EConsumeMode> ConsumeMode;

        inline bool IsEmpty(const TString& s) {
            if (s == "EMPTY") {
                TimeStart = Now();
                Status = asInProgress;
                IdTask = "EMPTY";
                Success("Nothing to do");
                return true;
            }
            return false;
        }

    protected:

        virtual NJson::TJsonValue DoSerializeToJson() const override;
        virtual void DoDeserializeFromJson(const NJson::TJsonValue& json) override;

        virtual void AddPrevActionsResult(const NRTYScript::ITasksInfo& info) override {
            TControllerAsyncAction::AddPrevActionsResult(info);
            if (IsEmpty(IdTask))
                return;
            if (!!IdRes && IdRes[0] == '$') {
                NJson::TJsonValue result;
                if (info.GetValueByPath(IdRes.substr(1), result)) {
                    IdRes = result.GetStringRobust();
                    if (IsEmpty(IdRes))
                        return;
                }
                else {
                    DEBUG_LOG << "Incorrect path " + IdRes << Endl;
                }
            }
        }

        virtual TString ActionName() const override {
            return SYNC_DOWNLOAD_ACTION_NAME;
        }

        static TFactory::TRegistrator<TDownloadAction> Registrator;

    public:

        TDownloadAction() : TControllerAsyncAction(NDaemonController::apStartAndWait) {}

        TDownloadAction(const TString& waitActionName)
            : TControllerAsyncAction(waitActionName) {

        }

        TDownloadAction(const TString& idRes, TAsyncPolicy asyncPolicy)
            : TControllerAsyncAction(asyncPolicy)
        {
            IdRes = idRes;
        }

        TDownloadAction(const TString& idRes, TAsyncPolicy asyncPolicy, NRTYServer::EConsumeMode consumeMode)
            : TControllerAsyncAction(asyncPolicy)
        {
            IdRes = idRes;
            ConsumeMode = consumeMode;
        }

        virtual TLockType GetLockType() const override {
            return ltWriteLock;
        }

        virtual TString DoBuildCommandStart() const override {
            if (IdRes[0] == '$' || !IdRes) {
                Fail("Incorrect preparing of download task: " + IdRes);
                return "";
            }
            TString command = "command=synchronizer&async=yes&action=sync&id_res=" + IdRes;
            if (ConsumeMode.Defined()) {
                command += "&consume_mode=" + ToString(ConsumeMode);
            }
            return command;
        }

        virtual TDuration GetWaitTimeoutDuration() const override {
            return TDuration::Days(30);
        }

        virtual void InterpretTaskReply(TAsyncTaskExecutor::TTask::TStatus taskStatus, const NJson::TJsonValue& result) override;

    };
}
