//
// Copyright © 2017 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//
#include "YoloDatabase.hpp"

#include <armnn/Exceptions.hpp>

#include <array>
#include <cstdint>
#include <tuple>
#include <utility>

#include <boost/assert.hpp>
#include <boost/format.hpp>
#include <boost/log/trivial.hpp>
#include <boost/numeric/conversion/cast.hpp>

#include "InferenceTestImage.hpp"

namespace
{
enum class YoloVocClass : unsigned int
{
    Aeroplane,
    Bicycle,
    Bird,
    Boat,
    Bottle,
    Bus,
    Car,
    Cat,
    Chair,
    Cow,
    DiningTable,
    Dog,
    Horse,
    Motorbike,
    Person,
    PottedPlant,
    Sheep,
    Sofa,
    Train,
    TvMonitor
};

template <typename E>
constexpr auto to_underlying(E e) noexcept
{
    return static_cast<std::underlying_type_t<E>>(e);
}

class ImageNotFoundException : public armnn::Exception
{
    using Exception::Exception;
};

using YoloInputOutput = std::pair<const char* const, YoloDetectedObject>;

const std::array<YoloInputOutput,1> g_PerTestCaseInputOutput =
{
    YoloInputOutput{
        "yolo_dog_448x448.png",
        { to_underlying(YoloVocClass::Dog), YoloBoundingBox{ 233.0f, 256.0f, 299.0f, 462.0f }, 0.5088733434677124f }
    },
};

} // namespace

YoloDatabase::YoloDatabase(const std::string& imageDir)
    : m_ImageDir(imageDir)
{
}

std::unique_ptr<YoloDatabase::TTestCaseData> YoloDatabase::GetTestCaseData(unsigned int testCaseId)
{
    testCaseId = testCaseId % boost::numeric_cast<unsigned int>(g_PerTestCaseInputOutput.size());
    const auto& testCaseInputOutput = g_PerTestCaseInputOutput[testCaseId];
    const std::string imagePath = m_ImageDir + testCaseInputOutput.first;

    // Loads test case input image.
    std::vector<float> imageData;
    try
    {
        InferenceTestImage image(imagePath.c_str());
        if (YoloImageWidth != image.GetWidth() || YoloImageHeight != image.GetHeight())
        {
            image.Resize(YoloImageWidth, YoloImageHeight, CHECK_LOCATION());
        }
        imageData = GetImageDataInArmNnLayoutAsNormalizedFloats(ImageChannelLayout::Rgb, image);
    }
    catch (const InferenceTestImageException& e)
    {
        BOOST_LOG_TRIVIAL(fatal) << "Failed to load test case " << testCaseId << " with error: " << e.what();
        return nullptr;
    }

    // Prepares test case output.
    std::vector<YoloDetectedObject> topObjectDetections;
    topObjectDetections.reserve(1);
    topObjectDetections.push_back(testCaseInputOutput.second);

    return std::make_unique<YoloTestCaseData>(std::move(imageData), std::move(topObjectDetections));
}
