//
// Copyright © 2024 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//
//
// Copyright © 2020 The TensorFlow Authors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//

#include "ActivationOperator.hpp"
#include "TosaRescaleOperatorUtils.hpp"

#include <layers/ActivationLayer.hpp>

// This function is paraphrased from:
// tensorflow/compiler/mlir/tosa/transforms/legalize_tfl.cc from function ConvertTFLLeakyReluOp
TosaSerializationBasicBlock* ConvertActivationToTosaOperator(const Layer* layer,
                                                             const std::vector<const TensorInfo*>& inputs,
                                                             const std::vector<const TensorInfo*>& outputs,
                                                             const ActivationDescriptor* activationDescriptor)
{
    if (inputs.size() != 1)
    {
        throw armnn::Exception("ConvertActivationToTosaOperator: 1 input tensors required.");
    }

    if (outputs.size() != 1)
    {
        throw armnn::Exception("ConvertActivationToTosaOperator: 1 output tensor required.");
    }

    std::string inputName       = std::string("input0_");
    std::string outputNameAlpha = std::string("intermediate1_") + GetUniqueTosaMappingID();
    std::string outputNameMul   = std::string("intermediate2_") + GetUniqueTosaMappingID();
    std::string outputName      = std::string("output0_");
    std::string blockName       = std::string("Op_ACTIVATION_block_") + GetUniqueTosaMappingID();

    // 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.
    if (layer != nullptr)
    {
        // Get the layers connected to the input slots and determine unique tensors names.
        Layer& connectedInputLayer = layer->GetInputSlot(0).GetConnectedOutputSlot()->GetOwningLayer();
        inputName = GenerateUniqueName(connectedInputLayer, 0);

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

    std::vector<TosaSerializationTensor*> tensors;

    // Only add input tensors if connected layer is an input layer.
    // As intermediate or constant tensors will be created separately.
    // There also can't be duplicate tensor.
    std::vector<int32_t> inputShape0;
    DType inputDType0 =  DType::DType_UNKNOWN;
    if(inputName.find("input0_") != std::string::npos)
    {
        inputShape0 = GetTosaTensorShape(inputs[0]->GetShape());
        inputDType0 = ArmNNToDType(inputs[0]->GetDataType());
        tensors.push_back(new TosaSerializationTensor(inputName, inputShape0, inputDType0, {}));
    }

    std::vector<int32_t> outputShape0 = GetTosaTensorShape(outputs[0]->GetShape());
    DType outputDType0 = ArmNNToDType(outputs[0]->GetDataType());
    tensors.push_back(new TosaSerializationTensor(outputName, outputShape0, outputDType0, {}));

#if TOSA_FWD_COMPAT_VERSION(0, 60, 0)
    std::string outputNameMAXMIN= std::string("intermediate3_") + GetUniqueTosaMappingID();

    if (inputDType0 == DType::DType_FP32)
    {
        // const_alpha
        TosaSerializationOperator* alphaOp = nullptr;
        TosaSerializationTensor* alphaTensor = nullptr;
        CreateConstTosaOperator<float>(outputNameAlpha,
                                       activationDescriptor->m_A,
                                       inputDType0,
                                       inputShape0,
                                       alphaOp,
                                       alphaTensor);
        tensors.push_back(alphaTensor);

        // mul
        int32_t shift = 0;
        TosaMulAttribute mulAttribute(shift);
        TosaSerializationOperator* mulOp = new TosaSerializationOperator(Op_MUL,
                                                                         Attribute_MulAttribute,
                                                                         &mulAttribute,
                                                                         {inputName, outputNameAlpha},
                                                                         {outputNameMul});
        tensors.push_back(new TosaSerializationTensor(outputNameMul, inputShape0, inputDType0, {}));

        TosaSerializationOperator* op = nullptr;
        if (activationDescriptor->m_A <= 1.0)
        {
            op = new TosaSerializationOperator(Op_MAXIMUM,
                                               Attribute_NONE,
                                               nullptr,
                                               {inputName, outputNameMul},
                                               {outputName});
        }
        else
        {
            op = new TosaSerializationOperator(Op_MINIMUM,
                                               Attribute_NONE,
                                               nullptr,
                                               {inputName, outputNameMul},
                                               {outputName});

        }

        // 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
                                               {alphaOp, mulOp, op},   // operators
                                               tensors,                // tensors
                                               {inputName},            // inputs
                                               {outputName});          // outputs
    }
    else
    {
        std::string outputNameRescaleAlpha      = std::string("intermediate3_") + GetUniqueTosaMappingID();
        std::string outputNameRescaleIdentity   = std::string("intermediate4_") + GetUniqueTosaMappingID();
        std::string outputNameRescaleMaxMin     = std::string("intermediate5_") + GetUniqueTosaMappingID();

        DType rescale_type      = DType::DType_INT32;
        float alpha             = activationDescriptor->m_A;
        double scale_alpha      = inputs[0]->GetQuantizationScale() * alpha / outputs[0]->GetQuantizationScale();
        double scale_identity   = inputs[0]->GetQuantizationScale() / outputs[0]->GetQuantizationScale();
        int32_t input_zp        = inputs[0]->GetQuantizationOffset();
        int32_t output_zp       = outputs[0]->GetQuantizationOffset();

        // Value op_rescale_alpha_in =
        //        buildRescale(rewriter, op, rescale_type, input, scale_alpha,
        //                     input_qtype.getZeroPoint(), 0, true, true);
        TosaSerializationOperator* rescaleAlphaOp = nullptr;
        TosaSerializationTensor* rescaleAlphaTensor = nullptr;
        CreateRescaleTosaOperator(inputName,
                                  outputNameRescaleAlpha,
                                  rescale_type,
                                  inputShape0,
                                  scale_alpha,
                                  input_zp,
                                  0,
                                  true,
                                  true,
                                  &rescaleAlphaOp,
                                  &rescaleAlphaTensor);
        tensors.push_back(rescaleAlphaTensor);

        // Value op_rescale_identity_in =
        //       buildRescale(rewriter, op, rescale_type, input, scale_identity,
        //                    input_qtype.getZeroPoint(), 0, true, true);
        TosaSerializationOperator* rescaleIdentityOp = nullptr;
        TosaSerializationTensor* rescaleIdentityTensor = nullptr;
        CreateRescaleTosaOperator(inputName,
                                  outputNameRescaleIdentity,
                                  rescale_type,
                                  inputShape0,
                                  scale_identity,
                                  input_zp,
                                  0,
                                  true,
                                  true,
                                  &rescaleIdentityOp,
                                  &rescaleIdentityTensor);
        tensors.push_back(rescaleIdentityTensor);

        // Value result_int32;
        // if (alpha <= 1.0) {
        //    auto max_op = CreateOpAndInfer<tosa::MaximumOp>(
        //            rewriter, op->getLoc(), rescale_type, op_rescale_identity_in,
        //            op_rescale_alpha_in);
        //    result_int32 = max_op.getResult();
        // } else {
        //    auto min_op = CreateOpAndInfer<tosa::MinimumOp>(
        //            rewriter, op->getLoc(), rescale_type, op_rescale_identity_in,
        //            op_rescale_alpha_in);
        //    result_int32 = min_op.getResult();
        // }
        TosaSerializationOperator* op = nullptr;
        if (alpha <= 1.0)
        {
            op = new TosaSerializationOperator(Op_MAXIMUM,
                                               Attribute_NONE,
                                               nullptr,
                                               {outputNameRescaleAlpha, outputNameRescaleIdentity},
                                               {outputNameRescaleMaxMin});
        }
        else
        {
            op = new TosaSerializationOperator(Op_MINIMUM,
                                               Attribute_NONE,
                                               nullptr,
                                               {outputNameRescaleAlpha, outputNameRescaleIdentity},
                                               {outputNameRescaleMaxMin});

        }
        tensors.push_back(new TosaSerializationTensor(outputNameRescaleMaxMin, inputShape0, rescale_type, {}));

        // Value output = buildRescaleFromInt32(rewriter, op, output_type, result_int32,
        //                                      1.0, output_qtype.getZeroPoint());
        TosaSerializationOperator* rescaleOutputOp = nullptr;
        CreateFromInt32RescaleTosaOperator(outputNameRescaleMaxMin,
                                           outputName,
                                           outputDType0,
                                           outputShape0,
                                           1.0,
                                           output_zp,
                                           &rescaleOutputOp,
                                           nullptr);

        // 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
                                               {rescaleAlphaOp, rescaleIdentityOp, op, rescaleOutputOp}, // operators
                                               tensors,                // tensors
                                               {inputName},            // inputs
                                               {outputName});          // outputs
    }
#else
    std::string outputNameZero  = std::string("intermediate3_") + GetUniqueTosaMappingID();
    std::string outputNameGE    = std::string("intermediate4_") + GetUniqueTosaMappingID();

    // const_zero
    TosaSerializationOperator* zeroOp = nullptr;
    TosaSerializationTensor* zeroTensor = nullptr;
    CreateConstTosaOperator<float>(outputNameZero,
                                   0.0f,
                                   inputDType0,
                                   inputShape0,
                                   zeroOp,
                                   zeroTensor);
    tensors.push_back(zeroTensor);

    // const_alpha
    TosaSerializationOperator* alphaOp = nullptr;
    TosaSerializationTensor* alphaTensor = nullptr;
    CreateConstTosaOperator<float>(outputNameAlpha,
                                   activationDescriptor->m_A,
                                   inputDType0,
                                   inputShape0,
                                   alphaOp,
                                   alphaTensor);
    tensors.push_back(alphaTensor);

    // mul
    int32_t shift = 0;
    TosaMulAttribute mulAttribute(shift);
    TosaSerializationOperator* mulOp = new TosaSerializationOperator(Op_MUL,
                                                                     Attribute_MulAttribute,
                                                                     &mulAttribute,
                                                                     {inputName, outputNameAlpha},
                                                                     {outputNameMul});
    tensors.push_back(new TosaSerializationTensor(outputNameMul, inputShape0, inputDType0, {}));

    // greater_equal
    TosaSerializationOperator* geOp = new TosaSerializationOperator(Op_GREATER_EQUAL,
                                                                    Attribute_NONE,
                                                                    nullptr,
                                                                    {inputName, outputNameZero},
                                                                    {outputNameGE});
    tensors.push_back(new TosaSerializationTensor(outputNameGE, outputShape0, DType::DType_BOOL, {}));

    // select
    TosaSerializationOperator* selOp = new TosaSerializationOperator(Op_SELECT,
                                                                     Attribute_NONE,
                                                                     nullptr,
                                                                     {outputNameGE, inputName, outputNameMul},
                                                                     {outputName});

    // 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
                                           {zeroOp, alphaOp, mulOp, geOp, selOp},   // operators
                                           tensors,                                 // tensors
                                           {inputName},                             // inputs
                                           {outputName});                           // outputs
#endif
}
