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

#pragma once

#include <armnn/INetwork.hpp>
#include <backendsCommon/test/CommonTestUtils.hpp>
#include <ResolveType.hpp>

namespace{

armnn::INetworkPtr CreateGatherNetwork(const armnn::TensorInfo& paramsInfo,
                                       const armnn::TensorInfo& indicesInfo,
                                       const armnn::TensorInfo& outputInfo,
                                       const std::vector<int32_t>& indicesData)
{
    armnn::INetworkPtr net(armnn::INetwork::Create());

    armnn::IConnectableLayer* paramsLayer = net->AddInputLayer(0);
    armnn::IConnectableLayer* indicesLayer = net->AddConstantLayer(armnn::ConstTensor(indicesInfo, indicesData));
    armnn::IConnectableLayer* gatherLayer = net->AddGatherLayer("gather");
    armnn::IConnectableLayer* outputLayer = net->AddOutputLayer(0, "output");
    Connect(paramsLayer, gatherLayer, paramsInfo, 0, 0);
    Connect(indicesLayer, gatherLayer, indicesInfo, 0, 1);
    Connect(gatherLayer, outputLayer, outputInfo, 0, 0);

    return net;
}

template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
void GatherEndToEnd(const std::vector<BackendId>& backends)
{
    armnn::TensorInfo paramsInfo({ 8 }, ArmnnType);
    armnn::TensorInfo indicesInfo({ 3 }, armnn::DataType::Signed32);
    armnn::TensorInfo outputInfo({ 3 }, ArmnnType);

    paramsInfo.SetQuantizationScale(1.0f);
    paramsInfo.SetQuantizationOffset(0);
    outputInfo.SetQuantizationScale(1.0f);
    outputInfo.SetQuantizationOffset(0);

    // Creates structures for input & output.
    std::vector<T> paramsData{
        1, 2, 3, 4, 5, 6, 7, 8
    };

    std::vector<int32_t> indicesData{
        7, 6, 5
    };

    std::vector<T> expectedOutput{
        8, 7, 6
    };

    // Builds up the structure of the network
    armnn::INetworkPtr net = CreateGatherNetwork(paramsInfo, indicesInfo, outputInfo, indicesData);

    BOOST_TEST_CHECKPOINT("create a network");

    std::map<int, std::vector<T>> inputTensorData = {{ 0, paramsData }};
    std::map<int, std::vector<T>> expectedOutputData = {{ 0, expectedOutput }};

    EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
}

template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
void GatherMultiDimEndToEnd(const std::vector<BackendId>& backends)
{
    armnn::TensorInfo paramsInfo({ 3, 2, 3}, ArmnnType);
    armnn::TensorInfo indicesInfo({ 2, 3 }, armnn::DataType::Signed32);
    armnn::TensorInfo outputInfo({ 2, 3, 2, 3 }, ArmnnType);

    paramsInfo.SetQuantizationScale(1.0f);
    paramsInfo.SetQuantizationOffset(0);
    outputInfo.SetQuantizationScale(1.0f);
    outputInfo.SetQuantizationOffset(0);

    // Creates structures for input & output.
    std::vector<T> paramsData{
         1,  2,  3,
         4,  5,  6,

         7,  8,  9,
        10, 11, 12,

        13, 14, 15,
        16, 17, 18
    };

    std::vector<int32_t> indicesData{
        1, 2, 1,
        2, 1, 0
    };

    std::vector<T> expectedOutput{
         7,  8,  9,
        10, 11, 12,
        13, 14, 15,
        16, 17, 18,
         7,  8,  9,
        10, 11, 12,

        13, 14, 15,
        16, 17, 18,
         7,  8,  9,
        10, 11, 12,
         1,  2,  3,
         4,  5,  6
    };

    // Builds up the structure of the network
    armnn::INetworkPtr net = CreateGatherNetwork(paramsInfo, indicesInfo, outputInfo, indicesData);

    BOOST_TEST_CHECKPOINT("create a network");

    std::map<int, std::vector<T>> inputTensorData = {{ 0, paramsData }};
    std::map<int, std::vector<T>> expectedOutputData = {{ 0, expectedOutput }};

    EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
}

} // anonymous namespace
