#include <maps/wikimap/mapspro/services/mrc/eye/lib/detect_road_marking/tests/fixture.h>

#include <maps/wikimap/mapspro/services/mrc/eye/lib/detect_road_marking/impl/batch.h>
#include <maps/wikimap/mapspro/services/mrc/eye/lib/detect_road_marking/impl/process.h>

#include <maps/wikimap/mapspro/services/mrc/eye/lib/location/include/rotation.h>
#include <maps/wikimap/mapspro/services/mrc/eye/lib/unit_test/include/frame.h>

#include <library/cpp/testing/unittest/registar.h>
#include <mapreduce/yt/tests/yt_unittest_lib/yt_unittest_lib.h>

namespace maps::mrc::eye::tests {

struct ProcessFixture : public Fixture {
    ProcessFixture() {
        auto txn = newTxn();

        devices = {
            {db::eye::MrcDeviceAttrs{"M1"}},
        };
        db::eye::DeviceGateway(*txn).insertx(devices);

        frames = {
            {
                devices[0].id(),
                common::ImageOrientation(common::Rotation::CW_180),
                makeUrlContext(1, "2s"),
                {1920, 1080}, time()
            },
        };
        db::eye::FrameGateway(*txn).insertx(frames);

        recognitions = {
            {
                frames[0].id(),
                frames[0].orientation(),
                db::eye::RecognitionType::DetectPanel,
                db::eye::RecognitionSource::Model,
                0, // version
                db::eye::DetectedPanel{
                    common::ImageBox(0, 85, 1920, 1080)//common::ImageBox(0, 0, 1920, 950)
                }
            },
        };
        db::eye::RecognitionGateway(*txn).insertx(recognitions);

        txn->commit();
    }
};

Y_UNIT_TEST_SUITE_F(process_tests, ProcessFixture)
{

Y_UNIT_TEST(base)
{
    const auto loader = FrameLoader::fromConfig(config());
    const auto client = NYT::NTesting::CreateTestClient();

    YtWorkerConfig yt;
    yt.client = client.Get();
    yt.frameLoader = &loader;
    yt.rootPath = "//tmp/detect_object/run";
    yt.partitionSize = 10;
    yt.concurrency = 1;
    yt.commit = false;
    yt.useGpu = false;

    auto txn = newTxn();
    db::TIds frameIds{frames[0].id()};
    auto [frameById, panelByFrameId] = loadDetectRoadMarkingInputData(*txn, frameIds);

    db::eye::Recognitions recognitions = process(yt, frameById, panelByFrameId);

    UNIT_ASSERT_EQUAL(recognitions.size(), 1u);

    const db::eye::Recognition& recognition = recognitions[0];
    UNIT_ASSERT_EQUAL(recognition.frameId(), frames[0].id());
    UNIT_ASSERT_EQUAL(recognition.orientation(), frames[0].orientation());
    UNIT_ASSERT_EQUAL(recognition.type(), db::eye::RecognitionType::DetectRoadMarking);
    UNIT_ASSERT_EQUAL(recognition.version(), 0);

    const auto roadMarkings = recognition.value<db::eye::DetectedRoadMarkings>();
    UNIT_ASSERT_EQUAL(roadMarkings.size(), 2u);

    auto it1 = std::find_if(roadMarkings.begin(), roadMarkings.end(),
        [](const db::eye::DetectedRoadMarking& item) {
            return item.type == traffic_signs::TrafficSign::RoadMarkingLaneDirectionFR;
        }
    );
    UNIT_ASSERT_EQUAL(it1 == roadMarkings.end(), false);
    UNIT_ASSERT_EQUAL(it1->box, common::ImageBox(844, 188, 1111, 268));

    auto it2 = std::find_if(roadMarkings.begin(), roadMarkings.end(),
        [](const db::eye::DetectedRoadMarking& item) {
            return item.type == traffic_signs::TrafficSign::RoadMarkingLaneDirectionF;
        }
    );
    UNIT_ASSERT_EQUAL(it2 == roadMarkings.end(), false);
    UNIT_ASSERT_EQUAL(it2->box, common::ImageBox(1364, 176, 1746, 260));
}

} // Y_UNIT_TEST_SUITE

} // namespace maps::mrc::eye::tests
