#include <maps/wikimap/mapspro/services/autocart/pipeline/libs/objects/include/building.h>
#include <maps/wikimap/mapspro/services/autocart/pipeline/libs/storage/include/assessors_results.h>
#include <maps/wikimap/mapspro/services/autocart/pipeline/libs/storage/include/strings.h>

#include <mapreduce/yt/interface/common.h>

namespace maps::wiki::autocart::pipeline {

namespace {

constexpr const char* STATE = "state";
constexpr const char* TASK_ID = "taskId";
constexpr const char* USER_ID = "workerId";
constexpr const char* LOGIN = "login";

} // namespace

const std::string& AssessorsResult::getName() {
    static const std::string NAME = "assessors";
    return NAME;
}

NYT::TNode AssessorsResult::toYTNode() const {
    NYT::TNode node = bld.toYTNode();
    node[RESULT_ID] = id;
    node[STATE] = TString(toString(state));
    node[USER_ID] = TString(assessorId);
    node[TASK_ID] = TString(taskId);
    if (login.has_value()) {
        node[LOGIN] = TString(login.value());
    }

    return node;
}

void AssessorsResult::toJson(json::ObjectBuilder& builder) const {
    bld.toJson(builder);
    builder[RESULT_ID] = id;
    builder[STATE] = toString(state);
    builder[USER_ID] = assessorId;
    builder[TASK_ID] = taskId;
    if (login.has_value()) {
        builder[LOGIN] = login.value();
    } else {
        builder[LOGIN] = json::null;
    }
}

AssessorsResult AssessorsResult::fromYTNode(const NYT::TNode& node) {
    AssessorsResult result;
    result.id = node[RESULT_ID].AsUint64();
    result.bld = Building::fromYTNode(node);
    fromString(node[STATE].AsString().data(), result.state);
    result.assessorId = node[USER_ID].AsString();
    result.taskId = node[TASK_ID].AsString();
    if (!node[LOGIN].IsNull()) {
        result.login = node[LOGIN].AsString();
    }

    return result;
}

AssessorsResult AssessorsResult::fromJson(const json::Value& value) {
    AssessorsResult result;
    result.id = value[RESULT_ID].as<uint64_t>();
    result.bld = Building::fromJson(value);
    fromString(value[STATE].as<std::string>(), result.state);
    result.assessorId = value[USER_ID].as<std::string>();
    result.taskId = value[TASK_ID].as<std::string>();
    if (!value[LOGIN].isNull()) {
        result.login = value[LOGIN].as<std::string>();
    }

    return result;
}

NYT::TTableSchema AssessorsResult::getTableSchema() {
    return NYT::TTableSchema()
        .AddColumn(REGION, NYT::EValueType::VT_STRING, NYT::ESortOrder::SO_ASCENDING)
        .AddColumn(ISSUE_ID, NYT::EValueType::VT_UINT64, NYT::ESortOrder::SO_ASCENDING)
        .AddColumn(RESULT_ID, NYT::EValueType::VT_UINT64)
        .AddColumn(USER_ID, NYT::EValueType::VT_STRING)
        .AddColumn(TASK_ID, NYT::EValueType::VT_STRING)
        .AddColumn(LOGIN, NYT::EValueType::VT_STRING)
        .AddColumn(STATE, NYT::EValueType::VT_STRING)
        .AddColumn(DUMP_DATE, NYT::EValueType::VT_STRING)
        .Strict(false);
}

bool AssessorsResult::operator==(const AssessorsResult& that) const {
    return id == that.id
        && bld == that.bld
        && state == that.state
        && assessorId == that.assessorId
        && taskId == that.taskId
        && login == that.login;
}

} // namespace maps::wiki::autocart::pipeline
