#include <util/generic/yexception.h>
#include <util/stream/output.h>
#include <library/cpp/string_utils/quote/quote.h>

#include "http_client.h"
#include "log.h"
#include "periodic.h"
#include "uuid.h"

namespace NWebmaster {

TString TPeriodicLog::DefaultHandler;
TString TPeriodicLog::RunId;

TPeriodicLog::TPeriodicLog(const TString &taskType)
    : CurrentTaskType(taskType)
{
}

TPeriodicLog::~TPeriodicLog() {
    try {
        NWebmaster::HttpGet(RequestStr(), 500);
    } catch(std::exception &e) {
        LOG_WARN("periodic log: %s", e.what());
    }
}

TString TPeriodicLog::RequestStr() {
    TString statusMsg = StatusMsg;
    TString errorMsg = ErrorMsg;

    CGIEscape(statusMsg);
    CGIEscape(errorMsg);

    if (RunId.empty()) {
        NewRunId();
    }

    if (CurrentTaskType.empty()) {
        ythrow yexception() << "No task type defined";
    }

    return Handler() + "?taskType=" + CurrentTaskType + "&runId=" + RunId + "&eventType=" + EventTypeStr() + "&state=\"" + statusMsg + "\"&error=\"" + errorMsg + "\"";
}

TPeriodicLog& TPeriodicLog::NewRunId() {
    RunId = RandomUUID();
    return *this;
}

TPeriodicLog& TPeriodicLog::Handler(const TString &handler) {
    CurrentHandler = handler;
    return *this;
}

TPeriodicLog& TPeriodicLog::TaskType(const TString &taskType) {
    CurrentTaskType = taskType;
    return *this;
}

TPeriodicLog& TPeriodicLog::Start(const TString &statusMsg) {
    StatusMsg = statusMsg;
    EventType = START;
    return *this;
}

TPeriodicLog& TPeriodicLog::Finish(const TString &statusMsg) {
    StatusMsg = statusMsg;
    EventType = FINISH;
    return *this;
}

TPeriodicLog& TPeriodicLog::Error(const TString &errorMsg) {
    ErrorMsg = errorMsg;
    EventType = ERROR;
    return *this;
}

void TPeriodicLog::SetDefaultHandler(const TString &handler) {
    DefaultHandler = handler;
}

const TString TPeriodicLog::EventTypeStr() const {
    switch (EventType) {
    case START:
        return "START";
    case FINISH:
        return "FINISH";
    case ERROR:
        return "ERROR";
    }
}

const TString& TPeriodicLog::Handler() const {
    if (!CurrentHandler.empty()) {
        return CurrentHandler;
    }

    if (!DefaultHandler.empty()) {
        return DefaultHandler;
    }

    ythrow yexception() << "No handler defined";
}

} //namespace NWebmaster
