#include "processors.h"
#include "messages.h"
#include <library/cpp/logger/global/global.h>
#include <util/system/execpath.h>

#define DEBUG_PROCESSOR_FAIL_AT_FIRST_NAME "fail_after_first_task_save"
#define DEBUG_PROCESSOR_FAIL_AT_START_REQUEST_PROCESSING "fail_start_request_processing"
#define DEBUG_PROCESSOR_FAIL_AT_BUILD_TASK "fail_at_build_task"
#define DM_PROCESSOR_EXIT_CODE -216

NRTY::TMessageProcessorsModule::TProcessorsFactory::TRegistrator<TDebugProcessorStopDMAfterTaskSave> TDebugProcessorStopDMAfterTaskSave::Registrator(DEBUG_PROCESSOR_FAIL_AT_FIRST_NAME);
NRTY::TMessageProcessorsModule::TProcessorsFactory::TRegistrator<TDebugProcessorDMRequestFailer> TDebugProcessorDMRequestFailer::Registrator(DEBUG_PROCESSOR_FAIL_AT_START_REQUEST_PROCESSING);

TString TDebugProcessorStopDMAfterTaskSave::Name() const {
    return DEBUG_PROCESSOR_FAIL_AT_FIRST_NAME;
}

bool TDebugProcessorStopDMAfterTaskSave::Process(IMessage* message) {
    TDebugMessageAfterSaveClusterTask* messDeb = dynamic_cast<TDebugMessageAfterSaveClusterTask*>(message);
    if (messDeb) {
        if (++Counter == 10) {
            INFO_LOG << "FAIL-counter-activation" << Endl;
            _exit(DM_PROCESSOR_EXIT_CODE);
        }
        return true;
    }
    return false;
}

TDebugProcessorStopDMAfterTaskSave::TDebugProcessorStopDMAfterTaskSave(const TString& /*info*/) {
    Counter = 0;
    TFsPath keyPath = TFsPath(GetExecPath()).Parent() / "deb_key_TDebugProcessorStopDMAfterTaskSave";
    keyPath.DeleteIfExists();
}

TString TDebugProcessorDMRequestFailer::Name() const {
    return DEBUG_PROCESSOR_FAIL_AT_START_REQUEST_PROCESSING"_" + Command;
}

bool TDebugProcessorDMRequestFailer::Process(IMessage* message) {
    TDebugMessageStartRequestProcessing* msg = dynamic_cast<TDebugMessageStartRequestProcessing*>(message);
    if (msg) {
        if (!Command || msg->GetCommand() == Command)
            ythrow yexception() << "Fail as intended";
        return true;
    }
    return false;
}

TDebugProcessorDMRequestFailer::TDebugProcessorDMRequestFailer(const TString& command)
    : Command(command)
{}

TString TDebugProcessorBuildTaskFailer::Name() const {
    return DEBUG_PROCESSOR_FAIL_AT_BUILD_TASK"_" + TaskType;
}

bool TDebugProcessorBuildTaskFailer::Process(IMessage* message) {
    TDebugMessageDoBuildTaskProcessing* msg = dynamic_cast<TDebugMessageDoBuildTaskProcessing*>(message);
    if (msg) {
        if (!TaskType || msg->GetTaskType() == TaskType)
            ythrow yexception() << "Fail as intended";
        return true;
    }
    return false;
}

TDebugProcessorBuildTaskFailer::TDebugProcessorBuildTaskFailer(const TString& taskType)
    : TaskType(taskType)
{}
