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

#include <cl/ClBackend.hpp>
#include <neon/NeonBackend.hpp>
#include <reference/RefBackend.hpp>
#include <armnn/BackendHelper.hpp>

#include <Network.hpp>

#include <doctest/doctest.h>

#include <vector>
#include <string>

using namespace armnn;

#if defined(ARMCOMPUTENEON_ENABLED)
// Disabled Test Suite
//TEST_SUITE("BackendsCompatibility")
//TEST_CASE("Neon_Cl_DirectCompatibility_Test")
//{
//    auto neonBackend = std::make_unique<NeonBackend>();
//    auto clBackend = std::make_unique<ClBackend>();
//
//    TensorHandleFactoryRegistry registry;
//    neonBackend->RegisterTensorHandleFactories(registry);
//    clBackend->RegisterTensorHandleFactories(registry);
//
//    const BackendId& neonBackendId = neonBackend->GetId();
//    const BackendId& clBackendId = clBackend->GetId();
//
//    BackendsMap backends;
//    backends[neonBackendId] = std::move(neonBackend);
//    backends[clBackendId] = std::move(clBackend);
//
//    armnn::Graph graph;
//
//    armnn::InputLayer* const inputLayer = graph.AddLayer<armnn::InputLayer>(0, "input");
//
//    inputLayer->SetBackendId(neonBackendId);
//
//    armnn::SoftmaxDescriptor smDesc;
//    armnn::SoftmaxLayer* const softmaxLayer1 = graph.AddLayer<armnn::SoftmaxLayer>(smDesc, "softmax1");
//    softmaxLayer1->SetBackendId(clBackendId);
//
//    armnn::SoftmaxLayer* const softmaxLayer2 = graph.AddLayer<armnn::SoftmaxLayer>(smDesc, "softmax2");
//    softmaxLayer2->SetBackendId(neonBackendId);
//
//    armnn::SoftmaxLayer* const softmaxLayer3 = graph.AddLayer<armnn::SoftmaxLayer>(smDesc, "softmax3");
//    softmaxLayer3->SetBackendId(clBackendId);
//
//    armnn::SoftmaxLayer* const softmaxLayer4 = graph.AddLayer<armnn::SoftmaxLayer>(smDesc, "softmax4");
//    softmaxLayer4->SetBackendId(neonBackendId);
//
//    armnn::OutputLayer* const outputLayer = graph.AddLayer<armnn::OutputLayer>(0, "output");
//    outputLayer->SetBackendId(clBackendId);
//
//    inputLayer->GetOutputSlot(0).Connect(softmaxLayer1->GetInputSlot(0));
//    softmaxLayer1->GetOutputSlot(0).Connect(softmaxLayer2->GetInputSlot(0));
//    softmaxLayer2->GetOutputSlot(0).Connect(softmaxLayer3->GetInputSlot(0));
//    softmaxLayer3->GetOutputSlot(0).Connect(softmaxLayer4->GetInputSlot(0));
//    softmaxLayer4->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
//
//    graph.TopologicalSort();
//
//    std::vector<std::string> errors;
//    auto result = SelectTensorHandleStrategy(graph, backends, registry, true, errors);
//
//    CHECK(result.m_Error == false);
//    CHECK(result.m_Warning == false);
//
//    OutputSlot& inputLayerOut = inputLayer->GetOutputSlot(0);
//    OutputSlot& softmaxLayer1Out = softmaxLayer1->GetOutputSlot(0);
//    OutputSlot& softmaxLayer2Out = softmaxLayer2->GetOutputSlot(0);
//    OutputSlot& softmaxLayer3Out = softmaxLayer3->GetOutputSlot(0);
//    OutputSlot& softmaxLayer4Out = softmaxLayer4->GetOutputSlot(0);
//
//    // Check that the correct factory was selected
//    CHECK(inputLayerOut.GetTensorHandleFactoryId()    == "Arm/Cl/TensorHandleFactory");
//    CHECK(softmaxLayer1Out.GetTensorHandleFactoryId() == "Arm/Cl/TensorHandleFactory");
//    CHECK(softmaxLayer2Out.GetTensorHandleFactoryId() == "Arm/Cl/TensorHandleFactory");
//    CHECK(softmaxLayer3Out.GetTensorHandleFactoryId() == "Arm/Cl/TensorHandleFactory");
//    CHECK(softmaxLayer4Out.GetTensorHandleFactoryId() == "Arm/Cl/TensorHandleFactory");
//
//    // Check that the correct strategy was selected
//    CHECK((inputLayerOut.GetEdgeStrategyForConnection(0) == EdgeStrategy::DirectCompatibility));
//    CHECK((softmaxLayer1Out.GetEdgeStrategyForConnection(0) == EdgeStrategy::DirectCompatibility));
//    CHECK((softmaxLayer2Out.GetEdgeStrategyForConnection(0) == EdgeStrategy::DirectCompatibility));
//    CHECK((softmaxLayer3Out.GetEdgeStrategyForConnection(0) == EdgeStrategy::DirectCompatibility));
//    CHECK((softmaxLayer4Out.GetEdgeStrategyForConnection(0) == EdgeStrategy::DirectCompatibility));
//
//    graph.AddCompatibilityLayers(backends, registry);
//
//    // Test for copy layers
//    int copyCount= 0;
//    graph.ForEachLayer([&copyCount](Layer* layer)
//    {
//        if (layer->GetType() == LayerType::MemCopy)
//        {
//            copyCount++;
//        }
//    });
//    CHECK(copyCount == 0);
//
//    // Test for import layers
//    int importCount= 0;
//    graph.ForEachLayer([&importCount](Layer *layer)
//    {
//        if (layer->GetType() == LayerType::MemImport)
//        {
//            importCount++;
//        }
//    });
//    CHECK(importCount == 0);
//}
//
//}
#endif

TEST_SUITE("BackendCapability")
{
#if defined(ARMNNREF_ENABLED)

TEST_CASE("Ref_Backends_Capability_Test")
{
    auto refBackend  = std::make_unique<RefBackend>();
    auto refCapabilities = refBackend->GetCapabilities();

    CHECK(armnn::HasCapability("NonConstWeights", refCapabilities));
    CHECK(armnn::HasCapability("AsyncExecution", refCapabilities));

    armnn::BackendOptions::BackendOption nonConstWeights{"NonConstWeights", true};
    armnn::BackendOptions::BackendOption AsyncExecution{"AsyncExecution", true};

    CHECK(armnn::HasCapability(nonConstWeights, refCapabilities));
    CHECK(armnn::HasCapability(AsyncExecution, refCapabilities));
}

TEST_CASE("Ref_Backends_Unkown_Capability_Test")
{
    auto refBackend  = std::make_unique<RefBackend>();
    auto refCapabilities = refBackend->GetCapabilities();

    armnn::BackendOptions::BackendOption AsyncExecutionFalse{"AsyncExecution", false};
    CHECK(!armnn::HasCapability(AsyncExecutionFalse, refCapabilities));

    armnn::BackendOptions::BackendOption AsyncExecutionInt{"AsyncExecution", 50};
    CHECK(!armnn::HasCapability(AsyncExecutionFalse, refCapabilities));

    armnn::BackendOptions::BackendOption AsyncExecutionFloat{"AsyncExecution", 0.0f};
    CHECK(!armnn::HasCapability(AsyncExecutionFloat, refCapabilities));

    armnn::BackendOptions::BackendOption AsyncExecutionString{"AsyncExecution", "true"};
    CHECK(!armnn::HasCapability(AsyncExecutionString, refCapabilities));

    CHECK(!armnn::HasCapability("Telekinesis", refCapabilities));
    armnn::BackendOptions::BackendOption unkownCapability{"Telekinesis", true};
    CHECK(!armnn::HasCapability(unkownCapability, refCapabilities));
}

#endif

#if defined(ARMCOMPUTENEON_ENABLED)

TEST_CASE("Neon_Backends_Capability_Test")
{
    auto neonBackend = std::make_unique<NeonBackend>();
    auto neonCapabilities = neonBackend->GetCapabilities();

    CHECK(armnn::HasCapability("NonConstWeights", neonCapabilities));
    CHECK(armnn::HasCapability("AsyncExecution", neonCapabilities));

    armnn::BackendOptions::BackendOption nonConstWeights{"NonConstWeights", false};
    armnn::BackendOptions::BackendOption AsyncExecution{"AsyncExecution", false};

    CHECK(armnn::HasCapability(nonConstWeights, neonCapabilities));
    CHECK(armnn::HasCapability(AsyncExecution, neonCapabilities));
}

#endif

#if defined(ARMCOMPUTECL_ENABLED)

TEST_CASE("Cl_Backends_Capability_Test")
{
    auto clBackend = std::make_unique<ClBackend>();
    auto clCapabilities = clBackend->GetCapabilities();

    CHECK(armnn::HasCapability("NonConstWeights", clCapabilities));
    CHECK(armnn::HasCapability("AsyncExecution", clCapabilities));

    armnn::BackendOptions::BackendOption nonConstWeights{"NonConstWeights", false};
    armnn::BackendOptions::BackendOption AsyncExecution{"AsyncExecution", false};

    CHECK(armnn::HasCapability(nonConstWeights, clCapabilities));
    CHECK(armnn::HasCapability(AsyncExecution, clCapabilities));
}

#endif

}
