#include <maps/wikimap/ugc/prepare_ammo/assignments/lib/prepare_ammo.h>
#include <yandex/maps/proto/ugc_account/backoffice.pb.h>

#include <maps/libs/common/include/exception.h>
#include <maps/libs/log8/include/log8.h>

namespace maps::wiki::ugc::ammo {

namespace {

size_t TASKS_FOR_USER_COUNT = 20;

// ya tool tvmknife unittest service --src 2020773 --dst 2025132
// from https://abc.yandex-team.ru/services/maps-core-feedback-api
// to https://abc.yandex-team.ru/services/maps-core-ugc-backoffice
// in testing
const std::string IMMORTAL_TICKET =
    "3:serv:CBAQ__________9_IggIpat7EKzNew:GgD_Xmc3CqWII6_mPxDZTwvyr_A8QGOWhUR"
    "cs5gOTOQs2LyxjL1hM0zZ-8ge3UQkoRV5dGIqspyCueELStJRYbrngDt2KngiDc-Tfs56-3yp"
    "DruR8C0nP0VHGR1SbvT7-2QHWD5cNUtjdO8AhP5Ad7FiBo6Z1c5gP45Wk9jLVGw";

namespace proto = yandex::maps::proto::ugc_account;

proto::assignment::AssignmentMetadata makeAddressAssignment()
{
    proto::assignment::AssignmentMetadata metadata;
    auto* addressAddAssignment = metadata.mutable_address_add_assignment();
    *addressAddAssignment->mutable_uri() = "ymapsbm1://pin?ll=37.55,37.55";
    return metadata;
}

proto::assignment::AssignmentMetadata makeOrgAssignment(size_t userIndex, size_t taskIndex)
{
    proto::assignment::AssignmentMetadata metadata;
    auto* orgStatusAssignment = metadata.mutable_organization_edit_status_assignment();
    *orgStatusAssignment->mutable_uri() =
        "ymapsbm1://org?oid=" + std::to_string(userIndex) + std::to_string(taskIndex);
    return metadata;
}

} // namespace

void writeAmmo(std::ofstream& out, size_t userIndex)
{
    static const std::string HEADERS =
        "X-Ya-Service-Ticket: " + IMMORTAL_TICKET + "\n"
        "Host: core-ugc-backoffice.maps.yandex.net\n"
        "Accept: */*\n"
        "User-Agent: tank\n"
        "Content-Type: application/octet-stream\n";

    for (size_t taskIndex = 0; taskIndex < TASKS_FOR_USER_COUNT; ++taskIndex) {
        proto::backoffice::Task task;
        *task.add_uid() = std::to_string(userIndex);
        auto& langToMetadata = *task.mutable_lang_to_metadata();

        std::string idPrefix;
        if (userIndex % 2 == 0) {
            langToMetadata["ru_RU"] = makeOrgAssignment(userIndex, taskIndex);
            idPrefix = "os";
        } else {
            langToMetadata["ru_RU"] = makeAddressAssignment();
            idPrefix = "address_add";
        }
        std::string taskId = idPrefix + ":" + std::to_string(userIndex) + std::to_string(taskIndex);

        TString data;
        REQUIRE(
            task.SerializeToString(&data),
            "Problem occured while serializing proto data");
        std::string strData{data};
        std::string request =
            "PUT /v1/assignments/create?task_id=" + taskId + " HTTP/1.0\r\n" +
            HEADERS + "Content-Length: " + std::to_string(task.ByteSizeLong()) + "\r\n\r\n" +
            strData + "\r\n";

        out << request.size() << " assignment_create: " + idPrefix + "\n" << request;
    }
}

void makeAmmo(
    const std::string& ammoPath,
    size_t ammoSize)
{
    INFO() << "Loading tasks...";
    std::ofstream out(ammoPath, std::ios::binary);
    INFO() << "Writing assignments/create requests...";
    for (size_t i = 0; i < ammoSize; ++i) {
        writeAmmo(out, i);
    }
}

} // maps::wiki::ugc::ammo
