#include "fixture.h"
#include <maps/wikimap/mapspro/services/mrc/long_tasks/import_nexar/lib/metadata.h>
#include <maps/wikimap/mapspro/services/mrc/libs/db/include/nexar_import_tile_update_info.h>

#include <maps/libs/chrono/include/time_point.h>
#include <maps/libs/log8/include/log8.h>
#include <maps/libs/introspection/include/comparison.h>
#include <maps/libs/introspection/include/stream_output.h>

#include <library/cpp/testing/gtest/gtest.h>


namespace maps::mrc::db {
using introspection::operator==;
using maps::introspection::operator<<;
} // namespace maps::mrc::db

namespace maps::mrc::import_nexar::tests {


TEST_F(Fixture, metadata_load_and_save)
{
    log8::setLevel(log8::Level::DEBUG);

    const chrono::TimePoint DATE =
        chrono::parseSqlDateTime("2015-06-16 16:57:27.797396+03");

    const db::NexarImportTileUpdateInfos tilesUpdateInfos{
        {1, 2, 3, 4, 5},
        {6, 7, 8, 9, 10}
    };

    auto txn = pool().masterWriteableTransaction();
    Metadata metadata = loadMetadata(*txn);

    EXPECT_FALSE(metadata.lastSuccessRunTime().has_value());
    EXPECT_EQ(metadata.tileUpdateInfos().size(), 0u);

    metadata.setLastSuccessRunTime(DATE);
    metadata.setTileUpdateInfo(tilesUpdateInfos[0]);
    metadata.setTileUpdateInfo(tilesUpdateInfos[1]);

    saveMetadata(*txn, metadata);

    Metadata loadedMetadata = loadMetadata(*txn);

    EXPECT_EQ(metadata.lastSuccessRunTime(),
        loadedMetadata.lastSuccessRunTime());

    EXPECT_THAT(
        metadata.tileUpdateInfos(),
        ::testing::UnorderedElementsAreArray(tilesUpdateInfos)
    );
}

TEST(metadata_should, loadAndsetTileUpdateInfo) {
    const int32_t geoId = 231;
    const int16_t fc = 1;
    const int32_t x = 155;
    const int32_t y = 256;
    const int32_t z = 16;

    Metadata metadata;

    EXPECT_EQ(metadata.tileUpdateInfos().size(), 0u);

    auto loadedTileUpdateInfo = metadata.getTileUpdateInfo({geoId, fc, x, y, z});
    EXPECT_FALSE(loadedTileUpdateInfo.checkedAt().has_value());
    EXPECT_FALSE(loadedTileUpdateInfo.medianPhotoAgeDays().has_value());

    EXPECT_EQ(metadata.tileUpdateInfos().size(), 0u);

    db::NexarImportTileUpdateInfo tileUpdateInfo{
        geoId,
        fc,
        x,
        y,
        z,
        chrono::parseSqlDateTime("2015-06-16 16:57:27.797396+03"),
        5};

    metadata.setTileUpdateInfo(tileUpdateInfo);

    EXPECT_EQ(metadata.tileUpdateInfos().size(), 1u);
    loadedTileUpdateInfo = metadata.getTileUpdateInfo({geoId, fc, x, y, z});
    EXPECT_EQ(loadedTileUpdateInfo, tileUpdateInfo);

    tileUpdateInfo = db::NexarImportTileUpdateInfo{
        geoId,
        fc,
        x,
        y,
        z,
        chrono::parseSqlDateTime("2016-06-16 16:57:27.797396+03"),
        7};

    metadata.setTileUpdateInfo(tileUpdateInfo);
    EXPECT_EQ(metadata.tileUpdateInfos().size(), 1u);
    loadedTileUpdateInfo = metadata.getTileUpdateInfo({geoId, fc, x, y, z});
    EXPECT_EQ(loadedTileUpdateInfo, tileUpdateInfo);
}



} // maps::mrc::import_nexar::tests
