//
// Copyright © 2017 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//
#include <boost/test/unit_test.hpp>

#include <armnn/ArmNN.hpp>

#include <Graph.hpp>
#include <SubGraph.hpp>
#include <SubGraphSelector.hpp>

#include <backendsCommon/CpuTensorHandle.hpp>

using namespace armnn;

namespace
{

//
// this helper only works if all layers where the inputs connect to are not selected
//
SubGraph::InputSlots CreateInputsFrom(const std::vector<Layer *> & layers)
{
    SubGraph::InputSlots result;
    for (auto&& layer : layers)
    {
        for (auto&& it = layer->BeginInputSlots(); it != layer->EndInputSlots(); ++it)
        {
            result.push_back(&(*it));
        }
    }
    return result;
}

//
// this helper only works if all layers where the outputs connect to are not selected
//
SubGraph::OutputSlots CreateOutputsFrom(const std::vector<Layer *> & layers)
{
    SubGraph::OutputSlots result;
    for (auto && layer : layers)
    {
        for (auto&& it = layer->BeginOutputSlots(); it != layer->EndOutputSlots(); ++it)
        {
            result.push_back(&(*it));
        }
    }
    return result;
}

//
// this takes the inputs, outputs and layers as a copy and the move these copies into the
// resulting subgraph, so the pass bay value is intentional
//
SubGraphSelector::SubGraphPtr CreateSubGraphFrom(SubGraph::InputSlots inputs,
                                                 SubGraph::OutputSlots outputs,
                                                 SubGraph::Layers layers)
{
    return std::make_unique<SubGraph>(std::move(inputs), std::move(outputs), std::move(layers));
}

template <typename T, typename Iterator>
std::vector<T> ToSortedArray(Iterator begin, Iterator end)
{
    std::vector<T> result(begin, end);
    std::sort(result.begin(), result.end());
    return result;
}

template <typename T>
void CompareVectors(const std::vector<T> & result, const std::vector<T> & expected)
{
    BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
}

void CompareSubGraphs(SubGraphSelector::SubGraphPtr & result,
                      SubGraphSelector::SubGraphPtr & expected)
{
    // expect both to be valid subgraphs
    BOOST_TEST((result.get() != nullptr));
    BOOST_TEST((expected.get() != nullptr));

    if (result.get() != nullptr && expected.get() != nullptr)
    {
        // try to detect all other obvious errors too, mainly because here
        // we can get a nicer error message from boost, the collection test
        // also report error for these
        BOOST_TEST(result->GetInputSlots().size() == expected->GetInputSlots().size());
        BOOST_TEST(result->GetOutputSlots().size() == expected->GetOutputSlots().size());
        BOOST_TEST(result->GetLayers().size() == expected->GetLayers().size());

        auto resultLayers = ToSortedArray<Layer *>(result->GetLayers().begin(),
                                                   result->GetLayers().end());
        auto expectedLayers = ToSortedArray<Layer *>(expected->GetLayers().begin(),
                                                     expected->GetLayers().end());
        CompareVectors(resultLayers, expectedLayers);

        auto resultInputs = ToSortedArray<InputSlot *>(result->GetInputSlots().begin(),
                                                       result->GetInputSlots().end());
        auto expectedInputs = ToSortedArray<InputSlot *>(expected->GetInputSlots().begin(),
                                                         expected->GetInputSlots().end());
        CompareVectors(resultInputs, expectedInputs);

        auto resultOutputs = ToSortedArray<OutputSlot *>(result->GetOutputSlots().begin(),
                                                         result->GetOutputSlots().end());
        auto expectedOutputs = ToSortedArray<OutputSlot *>(expected->GetOutputSlots().begin(),
                                                           expected->GetOutputSlots().end());
        CompareVectors(resultOutputs, expectedOutputs);
    }
}

} // namespace <anonymous>

BOOST_AUTO_TEST_SUITE(SubGraphSelection)

BOOST_AUTO_TEST_CASE(NoSubGraphsForNoMatch)
{
    Graph graph;

    auto output = graph.AddLayer<OutputLayer>(0, "output");
    graph.InsertNewLayer<InputLayer>(output->GetInputSlot(0), 0, "input");

    SubGraphSelector::SubGraphs subGraphs =
        SubGraphSelector::SelectSubGraphs(graph, [](const Layer &) { return false; });

    BOOST_TEST(subGraphs.empty());
}

BOOST_AUTO_TEST_CASE(OneSubGraphsSelectedASingleMatch)
{
    Graph graph;

    auto output = graph.AddLayer<OutputLayer>(0, "output");
    graph.InsertNewLayer<InputLayer>(output->GetInputSlot(0), 0, "input");

    SubGraphSelector::SubGraphs subGraphs =
        SubGraphSelector::SelectSubGraphs(
            graph,
            // select the output layer only
            [](const Layer & l)
            {
                bool isOutput = l.GetNameStr().compare("output") == 0;
                return isOutput;
            });

    BOOST_TEST(subGraphs.size() == 1);
    if (subGraphs.size() == 1)
    {
        auto expected = CreateSubGraphFrom(CreateInputsFrom({output}),
                                           // outputs of 'output' will be empty
                                           CreateOutputsFrom({output}),
                                           {output});

        CompareSubGraphs(subGraphs[0], expected);
    }
}

BOOST_AUTO_TEST_CASE(MultipleLayersSelectedInTheMiddle)
{
    Graph graph;

    auto output = graph.AddLayer<OutputLayer>(0, "output");
    auto mid0 = graph.InsertNewLayer<ActivationLayer>(output->GetInputSlot(0),
                                                      ActivationDescriptor{},
                                                      "mid0");
    auto mid1 = graph.InsertNewLayer<ActivationLayer>(mid0->GetInputSlot(0),
                                                      ActivationDescriptor{},
                                                      "mid1");
    graph.InsertNewLayer<InputLayer>(mid1->GetInputSlot(0), 0, "input");

    SubGraphSelector::SubGraphs subGraphs =
        SubGraphSelector::SelectSubGraphs(
            graph,
            // select the middle layers only
            [](const Layer & l)
            {
                bool toSelect = (l.GetType() == LayerType::Activation);
                return toSelect;
            });

    BOOST_TEST(subGraphs.size() == 1);
    if (subGraphs.size() == 1)
    {
        auto expected = CreateSubGraphFrom(CreateInputsFrom({mid1}),
                                           CreateOutputsFrom({mid0}),
                                           {mid1, mid0});

        CompareSubGraphs(subGraphs[0], expected);
    }
}

BOOST_AUTO_TEST_CASE(IslandInTheMiddle)
{
    // This case represent the scenario when a non-selected X1 node placed in the middle
    // of the selected M* nodes:
    //
    // X0 -> M1 -> M2 -> M3 -> X2
    // X0 -> M4 -> X1 -> M5 -> X2
    //
    /*
          X0
          / \
        M1   M4
         |   |
        M2   X1 < the island in the middle !
         |   |
        M3   M5
          \ /
          X2
    */
    // The expected result for this is that M1,M2,M3,M4 will be part of one subgraph and
    // M5 will be part of another subgraph and the input and output slots in the subgraphs
    // will be set accordingly.
    //
    Graph graph;

    OriginsDescriptor mergerDescriptor(2);
    auto x2 = graph.AddLayer<MergerLayer>(mergerDescriptor, "x2");
    auto m3 = graph.InsertNewLayer<ActivationLayer>(x2->GetInputSlot(0),
                                                    ActivationDescriptor{},
                                                    "m3");
    auto m2 = graph.InsertNewLayer<ActivationLayer>(m3->GetInputSlot(0),
                                                    ActivationDescriptor{},
                                                    "m2");
    auto m1 = graph.InsertNewLayer<ActivationLayer>(m2->GetInputSlot(0),
                                                    ActivationDescriptor{},
                                                    "m1");
    auto x0 = graph.InsertNewLayer<InputLayer>(m1->GetInputSlot(0), 0, "x0");

    auto m5 = graph.InsertNewLayer<ActivationLayer>(x2->GetInputSlot(1),
                                                    ActivationDescriptor{},
                                                    "m5");
    auto x1 = graph.InsertNewLayer<Convolution2dLayer>(m5->GetInputSlot(0),
                                                       Convolution2dDescriptor{},
                                                       "x1");
    auto m4 = graph.InsertNewLayer<ActivationLayer>(x1->GetInputSlot(0),
                                                    ActivationDescriptor{},
                                                    "m4");

    // Connect the other branch to the input layer
    x0->GetOutputSlot(0).Connect(m4->GetInputSlot(0));

    // All selected 'M*' layers will be of Activation type
    SubGraphSelector::SubGraphs subGraphs =
        SubGraphSelector::SelectSubGraphs(
            graph,
            // select the middle layers only
            [](const Layer & l)
            {
                bool toSelect = (l.GetType() == LayerType::Activation);
                return toSelect;
            });

    // expected results to test against
    auto largerSubGraph = CreateSubGraphFrom(CreateInputsFrom({m1, m4}),
                                             CreateOutputsFrom({m3, m4}),
                                             {m1, m4, m2, m3});

    auto smallerSubGraph = CreateSubGraphFrom(CreateInputsFrom({m5}),
                                              CreateOutputsFrom({m5}),
                                              {m5});

    BOOST_TEST(subGraphs.size() == 2);
    if (subGraphs.size() == 2)
    {
        // we need to have valid subgraph pointers here
        BOOST_TEST((subGraphs[0] != nullptr));
        BOOST_TEST((subGraphs[1] != nullptr));

        if (subGraphs[0].get() != nullptr && subGraphs[1].get() != nullptr)
        {
            // sort the subgraphs by layer size, so it is simpler to test
            std::sort(subGraphs.begin(), subGraphs.end(),
                [](SubGraphSelector::SubGraphPtr & lhs, SubGraphSelector::SubGraphPtr & rhs)
                {
                    return (lhs->GetLayers().size() < rhs->GetLayers().size());
                }
            );

            // one subgraph needs to be size=1 and the other one is 4
            BOOST_TEST(subGraphs[0]->GetLayers().size() == 1);
            BOOST_TEST(subGraphs[1]->GetLayers().size() == 4);

            CompareSubGraphs(subGraphs[0], smallerSubGraph);
            CompareSubGraphs(subGraphs[1], largerSubGraph);
        }
    }
}

BOOST_AUTO_TEST_CASE(MultipleSimpleSubGraphs)
{
    // This test case represents the scenario when we have two distinct subgraphs
    // in a simple linear network. The selected nodes are the M* and the
    // non-selected ones are the X*
    //
    // X1 -> M1 -> M2 -> X2 -> M3 -> X3
    //
    // The expected results is two subgraphs, one with {M1, M2} and another one
    // with {M3}
    //
    Graph graph;

    // the graph is constructed in reverse order
    auto x3 = graph.AddLayer<OutputLayer>(0, "output");
    auto m3 = graph.InsertNewLayer<ActivationLayer>(x3->GetInputSlot(0),
                                                    ActivationDescriptor{},
                                                    "m3");
    auto x2 = graph.InsertNewLayer<Convolution2dLayer>(m3->GetInputSlot(0),
                                                       Convolution2dDescriptor{},
                                                       "x2");
    auto m2 = graph.InsertNewLayer<ActivationLayer>(x2->GetInputSlot(0),
                                                    ActivationDescriptor{},
                                                    "m2");
    auto m1 = graph.InsertNewLayer<ActivationLayer>(m2->GetInputSlot(0),
                                                    ActivationDescriptor{},
                                                    "m1");
    graph.InsertNewLayer<InputLayer>(m1->GetInputSlot(0), 0, "x1");

    // All selected 'M*' layers will be of Activation type
    SubGraphSelector::SubGraphs subGraphs =
        SubGraphSelector::SelectSubGraphs(
            graph,
            // select the middle layers only
            [](const Layer & l)
            {
                bool toSelect = (l.GetType() == LayerType::Activation);
                return toSelect;
            });

    // expected results to test against
    auto largerSubGraph = CreateSubGraphFrom(CreateInputsFrom({m1}),
                                             CreateOutputsFrom({m2}),
                                             {m1, m2});

    auto smallerSubGraph = CreateSubGraphFrom(CreateInputsFrom({m3}),
                                              CreateOutputsFrom({m3}),
                                              {m3});

    BOOST_TEST(subGraphs.size() == 2);
    if (subGraphs.size() == 2)
    {
        // we need to have valid subgraph pointers here
        BOOST_TEST((subGraphs[0] != nullptr));
        BOOST_TEST((subGraphs[1] != nullptr));

        if (subGraphs[0].get() != nullptr && subGraphs[1].get() != nullptr)
        {
            // sort the subgraphs by layer size, so it is simpler to test
            std::sort(subGraphs.begin(), subGraphs.end(),
                [](SubGraphSelector::SubGraphPtr & lhs, SubGraphSelector::SubGraphPtr & rhs)
                {
                    return (lhs->GetLayers().size() < rhs->GetLayers().size());
                }
            );

            BOOST_TEST(subGraphs[0]->GetLayers().size() == 1);
            BOOST_TEST(subGraphs[1]->GetLayers().size() == 2);

            CompareSubGraphs(subGraphs[0], smallerSubGraph);
            CompareSubGraphs(subGraphs[1], largerSubGraph);
        }
    }
}

BOOST_AUTO_TEST_CASE(SimpleLinearTest)
{
    //X1 -> M1 -> M2 -> X2
    //Where the input slots of M1 and the output slots of M2 are to be the sub graph boundaries.
    Graph graph;

    ActivationDescriptor activationDefaults;

    auto layerX1 = graph.AddLayer<InputLayer>(0, "layerX1");
    auto layerX2 = graph.AddLayer<OutputLayer>(0, "layerX2");
    auto layerM1 = graph.AddLayer<ActivationLayer>(activationDefaults, "layerM1");
    auto layerM2 = graph.AddLayer<ActivationLayer>(activationDefaults, "layerM2");

    //      X1
    //      |
    //      M1
    //      |
    //      M2
    //      |
    //      X2

    layerX1->GetOutputSlot(0).Connect(layerM1->GetInputSlot(0));
    layerM1->GetOutputSlot(0).Connect(layerM2->GetInputSlot(0));
    layerM2->GetOutputSlot(0).Connect(layerX2->GetInputSlot(0));

    SubGraphSelector::SubGraphs subGraphs =
            SubGraphSelector::SelectSubGraphs(
                    graph,
                    // select the activation layers M1 and M2
                    [](const Layer & l)
                    {
                        bool toSelect = (l.GetType() == LayerType::Activation);
                        return toSelect;
                    });

    BOOST_CHECK(subGraphs.size() == 1);
    if(subGraphs.size() == 1)
    {
        auto expected = CreateSubGraphFrom(CreateInputsFrom({layerM1}),
                                           CreateOutputsFrom({layerM2}),
                                           {layerM1, layerM2});

        CompareSubGraphs(subGraphs[0], expected);
    }
}

BOOST_AUTO_TEST_CASE(MultiInputSingleOutput)
{
    //X1 -> M1 -> M3 -> X3
    //X2 -> M2 -> M3 -> X3
    //Where the input slots of {M1, M2} and the output slots of M3 are to be the subgraph boundaries.
    Graph graph;

    ActivationDescriptor activationDefaults;

    auto layerX1 = graph.AddLayer<InputLayer>(0, "layerX1");
    auto layerX2 = graph.AddLayer<InputLayer>(1, "layerX2");
    auto layerM1 = graph.AddLayer<ActivationLayer>(activationDefaults, "layerM1");
    auto layerM2 = graph.AddLayer<ActivationLayer>(activationDefaults, "layerM2");
    auto layerM3 = graph.AddLayer<AdditionLayer>("layerM3");
    auto layerX3 = graph.AddLayer<OutputLayer>(0, "layerX3");

    //  X1  X2
    //  |   |
    //  M1  M2
    //   \  |
    //    \ |
    //     \|
    //      M3
    //      |
    //      |
    //      X3

    layerX1->GetOutputSlot(0).Connect(layerM1->GetInputSlot(0));
    layerX2->GetOutputSlot(0).Connect(layerM2->GetInputSlot(0));
    layerM1->GetOutputSlot(0).Connect(layerM3->GetInputSlot(0));
    layerM2->GetOutputSlot(0).Connect(layerM3->GetInputSlot(1));
    layerM3->GetOutputSlot(0).Connect(layerX3->GetInputSlot(0));

    SubGraphSelector::SubGraphs subGraphs =
            SubGraphSelector::SelectSubGraphs(
                    graph,
                    // select Activation and Addition Layers M1, M2 and M3
                    [](const Layer & l)
                    {
                        bool toSelect = (l.GetType() == LayerType::Activation
                                         || l.GetType() == LayerType::Addition);
                        return toSelect;
                    });

    BOOST_CHECK(subGraphs.size() == 1);
    if (subGraphs.size() == 1)
    {
        auto expected = CreateSubGraphFrom(CreateInputsFrom({layerM1, layerM2}),
                                           CreateOutputsFrom({layerM3}),
                                           {layerM1, layerM2, layerM3});

        CompareSubGraphs(subGraphs[0], expected);
    }
}

BOOST_AUTO_TEST_CASE(SingleInputMultiOutput)
{
    //X1 -> M1 -> M2 -> X2
    //X1 -> M1 -> M3 -> X3
    //Where the input slots of M1 and the output slots of {M2, M3} are to be the subgraph boundaries.
    Graph graph;

    ActivationDescriptor activationDefaults;
    ViewsDescriptor viewDefaults(2,4);

    Layer* layerX1 = graph.AddLayer<InputLayer>(0, "layerX1");
    Layer* layerM1 = graph.AddLayer<SplitterLayer>(viewDefaults, "layerM1");
    Layer* layerM2 = graph.AddLayer<ActivationLayer>(activationDefaults, "layerM2");
    Layer* layerM3 = graph.AddLayer<ActivationLayer>(activationDefaults, "layerM3");
    Layer* layerX2 = graph.AddLayer<OutputLayer>(0, "layerX2");
    Layer* layerX3 = graph.AddLayer<OutputLayer>(1, "layerX3");

    //      X2
    //      |
    //      M1
    //     /|
    //    / |
    //   /  |
    //  M2  M3
    //  |   |
    //  |   |
    //  X2  X3

    layerX1->GetOutputSlot(0).Connect(layerM1->GetInputSlot(0));
    layerM1->GetOutputSlot(0).Connect(layerM2->GetInputSlot(0));
    layerM1->GetOutputSlot(1).Connect(layerM3->GetInputSlot(0));
    layerM2->GetOutputSlot(0).Connect(layerX2->GetInputSlot(0));
    layerM3->GetOutputSlot(0).Connect(layerX3->GetInputSlot(0));

    SubGraphSelector::SubGraphs subGraphs =
            SubGraphSelector::SelectSubGraphs(
                    graph,
                    // select Activation and Splitter Layers M1, M2 and M3
                    [](const Layer & l)
                    {
                        bool toSelect = (l.GetType() == LayerType::Activation
                                         || l.GetType() == LayerType::Splitter);
                        return toSelect;
                    });

    BOOST_CHECK(subGraphs.size() == 1);
    if(subGraphs.size() == 1)
    {
        auto expected = CreateSubGraphFrom(CreateInputsFrom({layerM1}),
                                           CreateOutputsFrom({layerM2, layerM3}),
                                           {layerM1, layerM2, layerM3});

        CompareSubGraphs(subGraphs[0], expected);
    }
}

BOOST_AUTO_TEST_CASE(MultiInputMultiOutput)
{
    // This case represents the scenario with multiple inputs and multiple outputs
    //
    // X1 -> M1 -> M3 -> M4 -> X3
    // X2 -> M2 -> M3 -> M5 -> X4
    //
    // Where the input slots of {M1, M2} and the output slots of {M4, M5} are to be the subgraph
    // boundaries.

    Graph graph;

    ActivationDescriptor activationDefaults;
    OriginsDescriptor mergerDescriptor(2);

    auto x1 = graph.AddLayer<InputLayer>(0, "x1");
    auto x2 = graph.AddLayer<InputLayer>(1, "x2");

    auto m1 = graph.AddLayer<ActivationLayer>(activationDefaults, "m1");
    auto m2 = graph.AddLayer<ActivationLayer>(activationDefaults, "m2");
    auto m3 = graph.AddLayer<MergerLayer>(mergerDescriptor, "m3");

    auto m4 = graph.AddLayer<ActivationLayer>(activationDefaults, "m4");
    auto m5 = graph.AddLayer<ActivationLayer>(activationDefaults, "m5");

    auto x3 = graph.AddLayer<OutputLayer>(0, "x3");
    auto x4 = graph.AddLayer<OutputLayer>(1, "x4");

    x1->GetOutputSlot(0).Connect(m1->GetInputSlot(0));
    x2->GetOutputSlot(0).Connect(m2->GetInputSlot(0));

    m1->GetOutputSlot(0).Connect(m3->GetInputSlot(0));
    m2->GetOutputSlot(0).Connect(m3->GetInputSlot(1));

    m3->GetOutputSlot(0).Connect(m4->GetInputSlot(0));
    m3->GetOutputSlot(0).Connect(m5->GetInputSlot(0));

    m4->GetOutputSlot(0).Connect(x3->GetInputSlot(0));
    m5->GetOutputSlot(0).Connect(x4->GetInputSlot(0));


    SubGraphSelector::SubGraphs subGraphs =
        SubGraphSelector::SelectSubGraphs(
            graph,
            // select Activation and Merger Layers M1, M2, M3, M4, M5
            [](const Layer & l)
            {
                bool toSelect = (l.GetType() == LayerType::Activation
                                 || l.GetType() == LayerType::Merger);
                return toSelect;
            });


    BOOST_CHECK(subGraphs.size() == 1);
    if (subGraphs.size() == 1)
    {
        auto expected = CreateSubGraphFrom(CreateInputsFrom({m1, m2}),
                                           CreateOutputsFrom({m4, m5}),
                                           {m1, m2, m3, m4, m5});

        CompareSubGraphs(subGraphs[0], expected);
    }
}

BOOST_AUTO_TEST_SUITE_END()
