//
// Copyright © 2022-2024 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//

#include "ConcatOperator.hpp"

TosaSerializationBasicBlock* ConvertConcatToTosaOperator(const Layer* layer,
                                                         const std::vector<const TensorInfo*>& inputs,
                                                         const std::vector<const TensorInfo*>& outputs,
                                                         const OriginsDescriptor* concatDescriptor)
{
    auto numInputs = inputs.size();
    std::vector<std::string> inputNames;
    inputNames.reserve(numInputs);
    std::string outputName = std::string("output0_");
    std::string blockName  = std::string("Op_CONCAT_block_") + GetUniqueTosaMappingID();

    // Set input names for validation purposes only.
    if (layer == nullptr)
    {
        for (uint32_t i = 0; i < numInputs; ++i)
        {
            inputNames.push_back("input_"+ std::to_string(i));
        }
    }
    // If a layer is present then the block will be used for execution, so input and output names need to be determined
    // using the previous and following layers so the graph is connected correctly. For validation this doesn't matter.
    else
    {
        // Get the layers connected to the input slots and determine unique tensor names.
        for (uint32_t i = 0; i < numInputs; ++i)
        {
            std::string inputName = GenerateUniqueInputName(layer->GetInputSlot(i));
            inputNames.push_back(inputName);
        }

        // Determine unique output tensor name.
        outputName = GenerateUniqueOutputName(*layer);
    }

    auto axis = static_cast<int32_t>(concatDescriptor->GetConcatAxis());
    TosaAxisAttribute attribute(axis);

    TosaSerializationOperator* op = new TosaSerializationOperator(Op_CONCAT,
                                                                  Attribute_AxisAttribute,
                                                                  &attribute,
                                                                  inputNames,
                                                                  {outputName});

    std::vector<TosaSerializationTensor*> tensors;
    tensors.reserve(numInputs + 1);
    for (uint32_t i = 0; i < numInputs; ++i)
    {
        // Only add input tensors for validation or when the connected layer is an input layer.
        // As there can't be duplicate tensors and intermediate or constant tensors are created separately.
        if(inputNames[i].find("input") != std::string::npos)
        {
            std::vector<int32_t> inputShape = GetTosaTensorShape(inputs[i]->GetShape());
            DType inputDType = ArmNNToDType(inputs[i]->GetDataType());
            tensors.push_back(new TosaSerializationTensor(inputNames[i], inputShape, inputDType, {}));
        }
    }

    std::vector<int32_t> outputShape0 = GetTosaTensorShape(outputs[0]->GetShape());
    DType outputDType0 = ArmNNToDType(outputs[0]->GetDataType());

    TosaSerializationTensor* outputTensor0 = new TosaSerializationTensor(outputName, outputShape0, outputDType0, {});
    tensors.push_back(outputTensor0);

    // operatorInputNames/operatorOutputNames ends up being the same as
    // blockInputNames/blockOutputNames for one-to-one ArmNN to TOSA mappings
    return new TosaSerializationBasicBlock(blockName,     // name
                                           mainName,      // region name
                                           {op},          // operators
                                           tensors,       // tensors
                                           inputNames,    // inputs
                                           {outputName}); // outputs
}