#include <maps/wikimap/mapspro/services/mrc/libs/house_number_sign_detector/include/house_number_sign_detector.h>

#include <library/cpp/testing/gtest/gtest.h>
#include <library/cpp/testing/common/env.h>
#include <maps/libs/common/include/exception.h>

using namespace testing;

namespace maps::mrc::house_number_sign_detector {

namespace tests {

namespace {

cv::Mat loadImage(const std::string& name) {
    static const std::string IMAGES_DIR =
        "maps/wikimap/mapspro/services/mrc/libs/house_number_sign_detector/tests/images/";
    auto imagePath = static_cast<std::string>(BinaryPath(IMAGES_DIR + name));
    cv::Mat image = cv::imread(imagePath, cv::IMREAD_COLOR);
    REQUIRE(image.data != nullptr, "Can't load image " << name);
    return image;
}

const std::string TEST_IMAGE_PATH = "house_number_sign_detector_test_image.jpg";
const cv::Rect    TEST_IMAGE_RECT(1823, 560, 34, 34);
const std::string TEST_HOUSE_NUMBER = "37";

} //namespace

TEST(basic_tests, detect_house_number_signs_on_images)
{
    FasterRCNNDetector detector;
    cv::Mat image = loadImage(TEST_IMAGE_PATH);
    HouseNumberSigns objects = detector.detect(image);
    EXPECT_THAT(objects.size(), Eq((size_t)1));
}

TEST(basic_tests, detect_house_number_signs_on_batch)
{
    FasterRCNNDetector detector;

    std::vector<cv::Mat> batch(2);
    batch[0] = loadImage(TEST_IMAGE_PATH);
    batch[1] = cv::Mat::zeros(batch[0].size(), batch[0].type());

    std::vector<HouseNumberSigns> objects = detector.detect(batch);
    EXPECT_THAT(objects.size(), Eq((size_t)2));

    EXPECT_THAT(objects[0].size(), Eq((size_t)1));

    EXPECT_THAT(objects[1].size(), Eq((size_t)0));
}

TEST(basic_tests, detect_and_recognize_house_number_signs_on_images)
{
    FasterRCNNDetector detector;

    cv::Mat image = loadImage(TEST_IMAGE_PATH);

    HouseNumberSigns objects = detector.detect(image,  RecognizeNumber::Yes);
    EXPECT_THAT(objects.size(), Eq((size_t)1));

    EXPECT_THAT(objects[0].number, TEST_HOUSE_NUMBER);
    EXPECT_THAT((objects[0].box & TEST_IMAGE_RECT).area(), Gt(TEST_IMAGE_RECT.area() / 2));
    EXPECT_THAT(objects[0].confidence, Gt(0.9f));
}

TEST(basic_tests, detect_and_recognize_house_number_signs_on_batch)
{
    FasterRCNNDetector detector;

    std::vector<cv::Mat> batch(2);
    batch[0] = loadImage(TEST_IMAGE_PATH);
    batch[1] = cv::Mat::zeros(batch[0].size(), batch[0].type());

    std::vector<HouseNumberSigns> objects = detector.detect(batch,  RecognizeNumber::Yes);
    EXPECT_THAT(objects.size(), Eq((size_t)2));

    EXPECT_THAT(objects[0].size(), Eq((size_t)1));

    const HouseNumberSign &object = objects[0][0];
    EXPECT_THAT(object.number, TEST_HOUSE_NUMBER);
    EXPECT_THAT((object.box & TEST_IMAGE_RECT).area(), Gt(TEST_IMAGE_RECT.area() / 2));
    EXPECT_THAT(object.confidence, Gt(0.9f));

    EXPECT_THAT(objects[1].size(), Eq((size_t)0));
}

} // namespace tests
} // namespace maps::mrc::house_number_sign_detector
