#include <maps/libs/json/include/value.h>
#include <maps/wikimap/mapspro/services/mrc/libs/toloka_client/pool_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/pool.h>

#include <library/cpp/testing/gtest_boost_extensions/extensions.h>

#include <chrono>

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

TEST_F(TolokaClientFixture, test_get_pools)
{
    Filter filter;
    filter.byProjectId("project-123");

    auto response = client().getPools(filter);
    const auto& pools = response.pools();

    EXPECT_FALSE(response.hasMore());
    EXPECT_EQ(pools.size(), 2u);

    // Check pool 1 properties
    EXPECT_EQ(pools[0].id(), "1");
    EXPECT_EQ(pools[0].projectId(), "project_1");
    EXPECT_EQ(pools[0].status(), PoolStatus::Closed);
    EXPECT_EQ(
        chrono::formatIsoDateTime(pools[0].createdAt()),
        "2016-10-31T09:31:53.624000000Z"
    );
    EXPECT_EQ(
        chrono::formatIsoDateTime(pools[0].expiresAt()),
        "2017-10-31T15:30:13.521000000Z"
    );
    EXPECT_TRUE(pools[0].lastStopped());
    EXPECT_EQ(
        chrono::formatIsoDateTime(*(pools[0].lastStopped())),
        "2016-11-17T08:35:22.293000000Z"
    );
    EXPECT_EQ(pools[0].rewardPerAssignment(), 0.01);
    EXPECT_EQ(pools[0].assignmentMaxDurationSec(), 1800u);
    EXPECT_EQ(pools[0].defaultOverlapTaskSuites(), 3u);
    EXPECT_TRUE(pools[0].hasAdultContent());
    EXPECT_TRUE(pools[0].autoAcceptSolutions());
    EXPECT_EQ(pools[0].lastCloseReason(), PoolCloseReason::Manual);

    // Check pool 2 properties
    EXPECT_EQ(pools[1].id(), "2");
    EXPECT_EQ(pools[1].projectId(), "project_1");
    EXPECT_EQ(pools[1].status(), PoolStatus::Open);
    EXPECT_EQ(
        chrono::formatIsoDateTime(pools[1].createdAt()),
        "2016-10-31T13:47:55.740000000Z"
    );
    EXPECT_EQ(
        chrono::formatIsoDateTime(pools[1].expiresAt()),
        "2017-10-31T16:47:20.751000000Z"
    );
    EXPECT_TRUE(pools[1].lastStopped());
    EXPECT_EQ(
        chrono::formatIsoDateTime(*(pools[1].lastStopped())),
        "2016-11-17T08:35:22.293000000Z"
    );
    EXPECT_EQ(pools[1].rewardPerAssignment(), 0.02);
    EXPECT_EQ(pools[1].assignmentMaxDurationSec(), 1800u);
    EXPECT_EQ(pools[1].defaultOverlapTaskSuites(), 3u);
    EXPECT_TRUE(pools[1].hasAdultContent());
    EXPECT_TRUE(pools[1].autoAcceptSolutions());
    EXPECT_FALSE(pools[1].lastCloseReason());
}

TEST_F(TolokaClientFixture, test_create_pool)
{
    auto response = client().getPools(Filter());
    const auto& pools = response.pools();
    EXPECT_FALSE(pools.empty());

    PoolCreationParams poolCreationParams(pools[0]);
    auto filter = json::Value::fromString("{\"is_odd\": true, \"color\": \"orange\"}");
    auto expiresAt = chrono::TimePoint() + std::chrono::hours(24);
    poolCreationParams.setExpiresAt(expiresAt).setFilter(filter);

    auto pool = client().createPool(poolCreationParams);
    EXPECT_EQ(pool.id(), "pool-123");
    EXPECT_GE(pool.createdAt(), chrono::TimePoint());
    EXPECT_EQ(pool.expiresAt(), expiresAt);

    // "filter" was set upon creation
    EXPECT_TRUE(pool.filter());
    EXPECT_TRUE(pool.filter().get()["is_odd"].as<bool>());
    EXPECT_EQ(pool.filter().get()["color"].as<std::string>(), "orange");

    // "quality_control" was inherited from the source pool
    EXPECT_TRUE(pool.qualityControl());
    EXPECT_EQ(pool.qualityControl().get()["dummy_year"].as<int>(), 2017);

    EXPECT_FALSE(pool.lastStopped());

    // "mixer_config" was not set
    EXPECT_FALSE(pool.mixerConfig());
}

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