#include <library/cpp/testing/common/env.h>
#include <library/cpp/testing/gtest/gtest.h>
#include <maps/wikimap/mapspro/services/mrc/libs/db/include/feature_gateway.h>
#include <maps/wikimap/mapspro/services/mrc/libs/db/include/object_in_photo_gateway.h>
#include <maps/wikimap/mapspro/services/mrc/tools/blur_mds/lib/process.h>
#include <maps/wikimap/mapspro/services/mrc/tools/blur_mds/lib/utility.h>
#include <yandex/maps/mrc/unittest/database_fixture.h>
#include <yandex/maps/mrc/unittest/local_server.h>

namespace maps::mrc::blur_mds::tests {

using namespace testing;

struct Fixture : testing::Test,
                 unittest::WithUnittestConfig<unittest::DatabaseFixture,
                                              unittest::MdsStubFixture> {
};

bool blurred(const db::Feature& feature)
{
    return std::string::npos != feature.mdsKey().path.find(BlurredSuffix);
}

TEST_F(Fixture, test)
{
    auto imageBlob = maps::common::readFileToString("opencv_1.jpg");
    auto mds = config().makeMdsClient();
    auto features = db::Features{
        db::Feature(std::string{"src0"},
                    geolib3::Point2(55.728255, 37.546717),
                    geolib3::Heading(331),
                    std::string{"2022-06-26 10:38:00+03"},
                    mds.post("0", imageBlob).key(),
                    db::Dataset::TaxiSignalQ2),
        db::Feature(std::string{"src1"},
                    geolib3::Point2(55.728254, 37.546716),
                    geolib3::Heading(150),
                    std::string{"2022-06-26 11:25:00+03"},
                    mds.post(concat("1/", BlurredSuffix), imageBlob).key(),
                    db::Dataset::TaxiSignalQ2),
        db::Feature(std::string{"src2"},
                    geolib3::Point2(56.322625, 44.010844),
                    geolib3::Heading(270),
                    std::string{"2022-06-26 11:41:00+03"},
                    mds.post("2", imageBlob).key(),
                    db::Dataset::Agents),
        db::Feature(std::string{"src3"},
                    geolib3::Point2(56.215127, 43.981049),
                    geolib3::Heading(113),
                    std::string{"2022-06-26 11:46:00+03"},
                    mds.post("3", imageBlob).key(),
                    db::Dataset::Agents),
    };
    {
        auto txn = pool().masterWriteableTransaction();
        db::FeatureGateway{*txn}.insert(features);
        txn->commit();
    }
    auto BlurredIndicesBefore = std::set{1};
    for (size_t index = 0; index < features.size(); ++index) {
        EXPECT_EQ(blurred(features.at(index)),
                  BlurredIndicesBefore.contains(index));
    }

    auto objects = db::ObjectsInPhoto{
        db::ObjectInPhoto(features.at(3).id(),
                          db::ObjectInPhotoType::LicensePlate,
                          common::ImageBox(0, 0, 1, 1),
                          1  ///< confidence
                          ),
    };
    {
        auto txn = pool().masterWriteableTransaction();
        db::ObjectInPhotoGateway{*txn}.insert(objects);
        txn->commit();
    }
    auto objectsByFeatureId =
        loadObjectsInPhoto(pool(), invokeForEach(features, &db::Feature::id));
    ASSERT(!objectsByFeatureId.empty());

    EXPECT_EQ(updateFeatures(pool(),
                             mds,
                             features,
                             objectsByFeatureId,
                             false  ///< dryRun
                             ),
              2u);
    auto BlurredIndicesAfter = std::set{0, 1, 3};
    for (size_t index = 0; index < features.size(); ++index) {
        EXPECT_EQ(blurred(features.at(index)),
                  BlurredIndicesAfter.contains(index));
    }

    features = db::FeatureGateway{*pool().masterReadOnlyTransaction()}.load();
    ASSERT(!features.empty());
    objectsByFeatureId =
        loadObjectsInPhoto(pool(), invokeForEach(features, &db::Feature::id));
    ASSERT(!objectsByFeatureId.empty());

    EXPECT_EQ(updateFeatures(pool(),
                             mds,
                             features,
                             objectsByFeatureId,
                             false  ///< dryRun
                             ),
              0u);
}

}  // namespace maps::mrc::blur_mds::tests
