//
// Copyright © 2017 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//
#pragma once

#include <ResolveType.hpp>

#include <armnn/Types.hpp>

#include <backendsCommon/CpuTensorHandle.hpp>
#include <backendsCommon/IBackendInternal.hpp>
#include <backendsCommon/WorkloadFactory.hpp>

#include <backendsCommon/test/TensorCopyUtils.hpp>
#include <backendsCommon/test/WorkloadFactoryHelper.hpp>
#include <backendsCommon/test/WorkloadTestUtils.hpp>

#include <test/TensorHelpers.hpp>

namespace
{

using FloatData = std::vector<float>;
using QuantData = std::pair<float, int32_t>;

struct TestData
{
    static const armnn::TensorShape s_BoxEncodingsShape;
    static const armnn::TensorShape s_ScoresShape;
    static const armnn::TensorShape s_AnchorsShape;

    static const QuantData s_BoxEncodingsQuantData;
    static const QuantData s_ScoresQuantData;
    static const QuantData s_AnchorsQuantData;

    static const FloatData s_BoxEncodings;
    static const FloatData s_Scores;
    static const FloatData s_Anchors;
};

struct RegularNmsExpectedResults
{
    static const FloatData s_DetectionBoxes;
    static const FloatData s_DetectionScores;
    static const FloatData s_DetectionClasses;
    static const FloatData s_NumDetections;
};

struct FastNmsExpectedResults
{
    static const FloatData s_DetectionBoxes;
    static const FloatData s_DetectionScores;
    static const FloatData s_DetectionClasses;
    static const FloatData s_NumDetections;
};

const armnn::TensorShape TestData::s_BoxEncodingsShape = { 1, 6, 4 };
const armnn::TensorShape TestData::s_ScoresShape       = { 1, 6, 3 };
const armnn::TensorShape TestData::s_AnchorsShape      = { 6, 4 };

const QuantData TestData::s_BoxEncodingsQuantData = { 1.00f, 1 };
const QuantData TestData::s_ScoresQuantData       = { 0.01f, 0 };
const QuantData TestData::s_AnchorsQuantData      = { 0.50f, 0 };

const FloatData TestData::s_BoxEncodings =
{
    0.0f,  0.0f, 0.0f, 0.0f,
    0.0f,  1.0f, 0.0f, 0.0f,
    0.0f, -1.0f, 0.0f, 0.0f,
    0.0f,  0.0f, 0.0f, 0.0f,
    0.0f,  1.0f, 0.0f, 0.0f,
    0.0f,  0.0f, 0.0f, 0.0f
};

const FloatData TestData::s_Scores =
{
    0.0f, 0.90f, 0.80f,
    0.0f, 0.75f, 0.72f,
    0.0f, 0.60f, 0.50f,
    0.0f, 0.93f, 0.95f,
    0.0f, 0.50f, 0.40f,
    0.0f, 0.30f, 0.20f
};

const FloatData TestData::s_Anchors =
{
    0.5f,   0.5f, 1.0f, 1.0f,
    0.5f,   0.5f, 1.0f, 1.0f,
    0.5f,   0.5f, 1.0f, 1.0f,
    0.5f,  10.5f, 1.0f, 1.0f,
    0.5f,  10.5f, 1.0f, 1.0f,
    0.5f, 100.5f, 1.0f, 1.0f
};

const FloatData RegularNmsExpectedResults::s_DetectionBoxes =
{
    0.0f, 10.0f, 1.0f, 11.0f,
    0.0f, 10.0f, 1.0f, 11.0f,
    0.0f,  0.0f, 0.0f,  0.0f
};

const FloatData RegularNmsExpectedResults::s_DetectionScores =
{
    0.95f, 0.93f, 0.0f
};

const FloatData RegularNmsExpectedResults::s_DetectionClasses =
{
    1.0f, 0.0f, 0.0f
};

const FloatData RegularNmsExpectedResults::s_NumDetections = { 2.0f };

const FloatData FastNmsExpectedResults::s_DetectionBoxes =
{
    0.0f,  10.0f, 1.0f,  11.0f,
    0.0f,   0.0f, 1.0f,   1.0f,
    0.0f, 100.0f, 1.0f, 101.0f
};

const FloatData FastNmsExpectedResults::s_DetectionScores =
{
    0.95f, 0.9f, 0.3f
};

const FloatData FastNmsExpectedResults::s_DetectionClasses =
{
    1.0f, 0.0f, 0.0f
};

const FloatData FastNmsExpectedResults::s_NumDetections = { 3.0f };

} // anonymous namespace

template<typename FactoryType,
         armnn::DataType ArmnnType,
         typename T = armnn::ResolveType<ArmnnType>>
void DetectionPostProcessImpl(const armnn::TensorInfo& boxEncodingsInfo,
                              const armnn::TensorInfo& scoresInfo,
                              const armnn::TensorInfo& anchorsInfo,
                              const std::vector<T>& boxEncodingsData,
                              const std::vector<T>& scoresData,
                              const std::vector<T>& anchorsData,
                              const std::vector<float>& expectedDetectionBoxes,
                              const std::vector<float>& expectedDetectionClasses,
                              const std::vector<float>& expectedDetectionScores,
                              const std::vector<float>& expectedNumDetections,
                              bool useRegularNms)
{
    std::unique_ptr<armnn::Profiler> profiler = std::make_unique<armnn::Profiler>();
    armnn::ProfilerManager::GetInstance().RegisterProfiler(profiler.get());

    auto memoryManager = WorkloadFactoryHelper<FactoryType>::GetMemoryManager();
    FactoryType workloadFactory = WorkloadFactoryHelper<FactoryType>::GetFactory(memoryManager);

    auto boxEncodings = MakeTensor<T, 3>(boxEncodingsInfo, boxEncodingsData);
    auto scores = MakeTensor<T, 3>(scoresInfo, scoresData);
    auto anchors = MakeTensor<T, 2>(anchorsInfo, anchorsData);

    armnn::TensorInfo detectionBoxesInfo({ 1, 3, 4 }, armnn::DataType::Float32);
    armnn::TensorInfo detectionScoresInfo({ 1, 3 }, armnn::DataType::Float32);
    armnn::TensorInfo detectionClassesInfo({ 1, 3 }, armnn::DataType::Float32);
    armnn::TensorInfo numDetectionInfo({ 1 }, armnn::DataType::Float32);

    LayerTestResult<float, 3> detectionBoxesResult(detectionBoxesInfo);
    detectionBoxesResult.outputExpected = MakeTensor<float, 3>(detectionBoxesInfo, expectedDetectionBoxes);
    LayerTestResult<float, 2> detectionClassesResult(detectionClassesInfo);
    detectionClassesResult.outputExpected = MakeTensor<float, 2>(detectionClassesInfo, expectedDetectionClasses);
    LayerTestResult<float, 2> detectionScoresResult(detectionScoresInfo);
    detectionScoresResult.outputExpected = MakeTensor<float, 2>(detectionScoresInfo, expectedDetectionScores);
    LayerTestResult<float, 1> numDetectionsResult(numDetectionInfo);
    numDetectionsResult.outputExpected = MakeTensor<float, 1>(numDetectionInfo, expectedNumDetections);

    std::unique_ptr<armnn::ITensorHandle> boxedHandle = workloadFactory.CreateTensorHandle(boxEncodingsInfo);
    std::unique_ptr<armnn::ITensorHandle> scoreshandle = workloadFactory.CreateTensorHandle(scoresInfo);
    std::unique_ptr<armnn::ITensorHandle> anchorsHandle = workloadFactory.CreateTensorHandle(anchorsInfo);
    std::unique_ptr<armnn::ITensorHandle> outputBoxesHandle = workloadFactory.CreateTensorHandle(detectionBoxesInfo);
    std::unique_ptr<armnn::ITensorHandle> classesHandle = workloadFactory.CreateTensorHandle(detectionClassesInfo);
    std::unique_ptr<armnn::ITensorHandle> outputScoresHandle = workloadFactory.CreateTensorHandle(detectionScoresInfo);
    std::unique_ptr<armnn::ITensorHandle> numDetectionHandle = workloadFactory.CreateTensorHandle(numDetectionInfo);

    armnn::ScopedCpuTensorHandle anchorsTensor(anchorsInfo);
    AllocateAndCopyDataToITensorHandle(&anchorsTensor, &anchors[0][0]);

    armnn::DetectionPostProcessQueueDescriptor data;
    data.m_Parameters.m_UseRegularNms = useRegularNms;
    data.m_Parameters.m_MaxDetections = 3;
    data.m_Parameters.m_MaxClassesPerDetection = 1;
    data.m_Parameters.m_DetectionsPerClass =1;
    data.m_Parameters.m_NmsScoreThreshold = 0.0;
    data.m_Parameters.m_NmsIouThreshold = 0.5;
    data.m_Parameters.m_NumClasses = 2;
    data.m_Parameters.m_ScaleY = 10.0;
    data.m_Parameters.m_ScaleX = 10.0;
    data.m_Parameters.m_ScaleH = 5.0;
    data.m_Parameters.m_ScaleW = 5.0;
    data.m_Anchors = &anchorsTensor;

    armnn::WorkloadInfo info;
    AddInputToWorkload(data,  info, boxEncodingsInfo, boxedHandle.get());
    AddInputToWorkload(data, info, scoresInfo, scoreshandle.get());
    AddOutputToWorkload(data, info, detectionBoxesInfo, outputBoxesHandle.get());
    AddOutputToWorkload(data, info, detectionClassesInfo, classesHandle.get());
    AddOutputToWorkload(data, info, detectionScoresInfo, outputScoresHandle.get());
    AddOutputToWorkload(data, info, numDetectionInfo, numDetectionHandle.get());

    std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateDetectionPostProcess(data, info);

    boxedHandle->Allocate();
    scoreshandle->Allocate();
    outputBoxesHandle->Allocate();
    classesHandle->Allocate();
    outputScoresHandle->Allocate();
    numDetectionHandle->Allocate();

    CopyDataToITensorHandle(boxedHandle.get(), boxEncodings.origin());
    CopyDataToITensorHandle(scoreshandle.get(), scores.origin());

    workload->Execute();

    CopyDataFromITensorHandle(detectionBoxesResult.output.origin(), outputBoxesHandle.get());
    CopyDataFromITensorHandle(detectionClassesResult.output.origin(), classesHandle.get());
    CopyDataFromITensorHandle(detectionScoresResult.output.origin(), outputScoresHandle.get());
    CopyDataFromITensorHandle(numDetectionsResult.output.origin(), numDetectionHandle.get());

    BOOST_TEST(CompareTensors(detectionBoxesResult.output, detectionBoxesResult.outputExpected));
    BOOST_TEST(CompareTensors(detectionClassesResult.output, detectionClassesResult.outputExpected));
    BOOST_TEST(CompareTensors(detectionScoresResult.output, detectionScoresResult.outputExpected));
    BOOST_TEST(CompareTensors(numDetectionsResult.output, numDetectionsResult.outputExpected));
}

template<armnn::DataType QuantizedType, typename RawType = armnn::ResolveType<QuantizedType>>
void QuantizeData(RawType* quant, const float* dequant, const armnn::TensorInfo& info)
{
    for (size_t i = 0; i < info.GetNumElements(); i++)
    {
        quant[i] = armnn::Quantize<RawType>(
            dequant[i], info.GetQuantizationScale(), info.GetQuantizationOffset());
    }
}

template<typename FactoryType>
void DetectionPostProcessRegularNmsFloatTest()
{
    return DetectionPostProcessImpl<FactoryType, armnn::DataType::Float32>(
        armnn::TensorInfo(TestData::s_BoxEncodingsShape, armnn::DataType::Float32),
        armnn::TensorInfo(TestData::s_ScoresShape, armnn::DataType::Float32),
        armnn::TensorInfo(TestData::s_AnchorsShape, armnn::DataType::Float32),
        TestData::s_BoxEncodings,
        TestData::s_Scores,
        TestData::s_Anchors,
        RegularNmsExpectedResults::s_DetectionBoxes,
        RegularNmsExpectedResults::s_DetectionClasses,
        RegularNmsExpectedResults::s_DetectionScores,
        RegularNmsExpectedResults::s_NumDetections,
        true);
}

template<typename FactoryType,
         armnn::DataType QuantizedType,
         typename RawType = armnn::ResolveType<QuantizedType>>
void DetectionPostProcessRegularNmsQuantizedTest()
{
    armnn::TensorInfo boxEncodingsInfo(TestData::s_BoxEncodingsShape, QuantizedType);
    armnn::TensorInfo scoresInfo(TestData::s_ScoresShape, QuantizedType);
    armnn::TensorInfo anchorsInfo(TestData::s_AnchorsShape, QuantizedType);

    boxEncodingsInfo.SetQuantizationScale(TestData::s_BoxEncodingsQuantData.first);
    boxEncodingsInfo.SetQuantizationOffset(TestData::s_BoxEncodingsQuantData.second);

    scoresInfo.SetQuantizationScale(TestData::s_ScoresQuantData.first);
    scoresInfo.SetQuantizationOffset(TestData::s_ScoresQuantData.second);

    anchorsInfo.SetQuantizationScale(TestData::s_AnchorsQuantData.first);
    anchorsInfo.SetQuantizationOffset(TestData::s_BoxEncodingsQuantData.second);

    std::vector<RawType> boxEncodingsData(TestData::s_BoxEncodingsShape.GetNumElements());
    QuantizeData<QuantizedType>(boxEncodingsData.data(),
                                TestData::s_BoxEncodings.data(),
                                boxEncodingsInfo);

    std::vector<RawType> scoresData(TestData::s_ScoresShape.GetNumElements());
    QuantizeData<QuantizedType>(scoresData.data(),
                                TestData::s_Scores.data(),
                                scoresInfo);

    std::vector<RawType> anchorsData(TestData::s_AnchorsShape.GetNumElements());
    QuantizeData<QuantizedType>(anchorsData.data(),
                                TestData::s_Anchors.data(),
                                anchorsInfo);

    return DetectionPostProcessImpl<FactoryType, QuantizedType>(
        boxEncodingsInfo,
        scoresInfo,
        anchorsInfo,
        boxEncodingsData,
        scoresData,
        anchorsData,
        RegularNmsExpectedResults::s_DetectionBoxes,
        RegularNmsExpectedResults::s_DetectionClasses,
        RegularNmsExpectedResults::s_DetectionScores,
        RegularNmsExpectedResults::s_NumDetections,
        true);
}

template<typename FactoryType>
void DetectionPostProcessFastNmsFloatTest()
{
    return DetectionPostProcessImpl<FactoryType, armnn::DataType::Float32>(
        armnn::TensorInfo(TestData::s_BoxEncodingsShape, armnn::DataType::Float32),
        armnn::TensorInfo(TestData::s_ScoresShape, armnn::DataType::Float32),
        armnn::TensorInfo(TestData::s_AnchorsShape, armnn::DataType::Float32),
        TestData::s_BoxEncodings,
        TestData::s_Scores,
        TestData::s_Anchors,
        FastNmsExpectedResults::s_DetectionBoxes,
        FastNmsExpectedResults::s_DetectionClasses,
        FastNmsExpectedResults::s_DetectionScores,
        FastNmsExpectedResults::s_NumDetections,
        false);
}

template<typename FactoryType,
         armnn::DataType QuantizedType,
         typename RawType = armnn::ResolveType<QuantizedType>>
void DetectionPostProcessFastNmsQuantizedTest()
{
    armnn::TensorInfo boxEncodingsInfo(TestData::s_BoxEncodingsShape, QuantizedType);
    armnn::TensorInfo scoresInfo(TestData::s_ScoresShape, QuantizedType);
    armnn::TensorInfo anchorsInfo(TestData::s_AnchorsShape, QuantizedType);

    boxEncodingsInfo.SetQuantizationScale(TestData::s_BoxEncodingsQuantData.first);
    boxEncodingsInfo.SetQuantizationOffset(TestData::s_BoxEncodingsQuantData.second);

    scoresInfo.SetQuantizationScale(TestData::s_ScoresQuantData.first);
    scoresInfo.SetQuantizationOffset(TestData::s_ScoresQuantData.second);

    anchorsInfo.SetQuantizationScale(TestData::s_AnchorsQuantData.first);
    anchorsInfo.SetQuantizationOffset(TestData::s_BoxEncodingsQuantData.second);

    std::vector<RawType> boxEncodingsData(TestData::s_BoxEncodingsShape.GetNumElements());
    QuantizeData<QuantizedType>(boxEncodingsData.data(),
                                TestData::s_BoxEncodings.data(),
                                boxEncodingsInfo);

    std::vector<RawType> scoresData(TestData::s_ScoresShape.GetNumElements());
    QuantizeData<QuantizedType>(scoresData.data(),
                                TestData::s_Scores.data(),
                                scoresInfo);

    std::vector<RawType> anchorsData(TestData::s_AnchorsShape.GetNumElements());
    QuantizeData<QuantizedType>(anchorsData.data(),
                                TestData::s_Anchors.data(),
                                anchorsInfo);

    return DetectionPostProcessImpl<FactoryType, QuantizedType>(
        boxEncodingsInfo,
        scoresInfo,
        anchorsInfo,
        boxEncodingsData,
        scoresData,
        anchorsData,
        FastNmsExpectedResults::s_DetectionBoxes,
        FastNmsExpectedResults::s_DetectionClasses,
        FastNmsExpectedResults::s_DetectionScores,
        FastNmsExpectedResults::s_NumDetections,
        false);
}
