#include <maps/wikimap/mapspro/services/mrc/libs/toloka_client/task_impl.h>
#include <maps/wikimap/mapspro/services/mrc/libs/toloka_client/tests/fixture.h>
#include <yandex/maps/mrc/toloka_client/client.h>
#include <yandex/maps/mrc/toloka_client/task.h>

namespace maps {
namespace mrc {
namespace toloka {
namespace io {
namespace test {

TEST_F(TolokaClientFixture, test_get_tasks)
{
    Filter filter;
    filter.byPoolId("pool-123");

    auto response = client().getTasks(filter);
    const auto& tasks = response.tasks();

    EXPECT_EQ(tasks.size(), 3u);

    // Check task 1 properties
    EXPECT_EQ(tasks[0].id(), "1");
    EXPECT_EQ(tasks[0].poolId(), "1");
    EXPECT_EQ(
        maps::chrono::formatIsoDateTime(tasks[0].createdAt()),
        "2016-09-07T08:49:27.272000000Z"
    );
    EXPECT_FALSE(tasks[0].hasInfiniteOverlap());
    EXPECT_EQ(*tasks[0].overlap(), 3u);

    const auto knownSolutions = tasks[0].knownSolutions();
    EXPECT_EQ(knownSolutions.size(), 2u);
    EXPECT_EQ(knownSolutions[0].correctnessWeight(), 1);
    EXPECT_TRUE(knownSolutions[0].outputValues().isObject());
    EXPECT_EQ(knownSolutions[1].correctnessWeight(), 0.95);
    EXPECT_TRUE(knownSolutions[1].outputValues().isObject());
    EXPECT_FALSE(tasks[0].messageOnUnknownSolution().empty());

    // Check task 2 properties
    EXPECT_EQ(tasks[1].id(), "2");
    EXPECT_EQ(tasks[1].poolId(), "1");
    EXPECT_EQ(
        maps::chrono::formatIsoDateTime(tasks[1].createdAt()),
        "2016-09-07T09:20:10Z"
    );
    EXPECT_FALSE(tasks[1].hasInfiniteOverlap());
    EXPECT_EQ(*tasks[1].overlap(), 3u);
    EXPECT_TRUE(tasks[1].knownSolutions().empty());
    EXPECT_TRUE(tasks[1].messageOnUnknownSolution().empty());

    // Check task 3 properties
    EXPECT_EQ(tasks[2].id(), "3");
    EXPECT_EQ(tasks[2].poolId(), "1");
    EXPECT_EQ(
        maps::chrono::formatIsoDateTime(tasks[2].createdAt()),
        "2016-09-07T09:21:10Z"
    );
    EXPECT_TRUE(tasks[2].hasInfiniteOverlap());
    EXPECT_FALSE(tasks[2].overlap());
    EXPECT_TRUE(tasks[2].knownSolutions().empty());
    EXPECT_TRUE(tasks[2].messageOnUnknownSolution().empty());
}

TEST_F(TolokaClientFixture, test_post_task)
{
    auto inputValues = json::Value::fromString("{\"month\": 12}");
    TaskCreationParams taskCreationParams("pool-123", inputValues);
    taskCreationParams.setOverlap(3);

    auto task = client().postTask(taskCreationParams);
    EXPECT_EQ(task.id(), "task-123");
    EXPECT_EQ(task.poolId(), "pool-123");
    EXPECT_GE(task.createdAt(), chrono::TimePoint());
    EXPECT_EQ(task.inputValues()["month"].as<size_t>(), 12u);
    EXPECT_FALSE(task.hasInfiniteOverlap());
    EXPECT_EQ(*task.overlap(), 3u);
}

TEST_F(TolokaClientFixture, test_post_multiple_tasks)
{
    std::vector<TaskCreationParams> paramsVec {
        TaskCreationParams("pool-123", json::Value::fromString("{\"month\": 9}")),
        TaskCreationParams("pool-456", json::Value::fromString("{\"month\": 12}"))
    };
    paramsVec[0].setOverlap(2);
    paramsVec[1].setInfiniteOverlap();

    auto tasksPostResp = client().postTasks(paramsVec);
    EXPECT_TRUE(tasksPostResp.errors().empty());
    const auto& tasks = tasksPostResp.tasks();

    EXPECT_EQ(tasks.size(), 2u);

    EXPECT_EQ(tasks.at(0).id(), "task-0");
    EXPECT_EQ(tasks.at(0).poolId(), "pool-123");
    EXPECT_GE(tasks.at(0).createdAt(), chrono::TimePoint());
    EXPECT_EQ(tasks.at(0).inputValues()["month"].as<size_t>(), 9u);
    EXPECT_FALSE(tasks.at(0).hasInfiniteOverlap());
    EXPECT_EQ(*(tasks.at(0).overlap()), 2u);

    EXPECT_EQ(tasks.at(1).id(), "task-1");
    EXPECT_EQ(tasks.at(1).poolId(), "pool-456");
    EXPECT_GE(tasks.at(1).createdAt(), chrono::TimePoint());
    EXPECT_EQ(tasks.at(1).inputValues()["month"].as<size_t>(), 12u);
    EXPECT_TRUE(tasks.at(1).hasInfiniteOverlap());
}

TEST_F(TolokaClientFixture, test_set_task_overlap)
{
    client().setTaskOverlap("task-123", 10);
}

} // test
} // namespace io
} // namespace toloka
} // namespace mrc
} // namespace maps
