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

#pragma once

#include "TestUtils.hpp"

#include <armnn_delegate.hpp>
#include <DelegateTestInterpreter.hpp>

#include <tensorflow/lite/version.h>

#include <armnn/utility/NumericCast.hpp>
#include <armnn/TypesUtils.hpp>

#include <armnn/Types.hpp>

#include <initializer_list>
#include <iterator>
#include <vector>

namespace
{

template<typename T>
std::vector<char> CreateUnidirectionalSequenceLstmTfLiteModel(tflite::TensorType tensorType,
                                                              int32_t batchSize,
                                                              int32_t timeSize,
                                                              int32_t inputSize,
                                                              int32_t outputSize,
                                                              int32_t numUnits,
                                                              bool hasInputToInputWeights,
                                                              const std::vector<T>& inputToInputWeights,
                                                              const std::vector<T>& inputToForgetWeights,
                                                              const std::vector<T>& inputToCellWeights,
                                                              const std::vector<T>& inputToOutputWeights,
                                                              bool hasRecurrentToInputWeights,
                                                              const std::vector<T>& recurrentToInputWeights,
                                                              const std::vector<T>& recurrentToForgetWeights,
                                                              const std::vector<T>& recurrentToCellWeights,
                                                              const std::vector<T>& recurrentToOutputWeights,
                                                              bool hasCellToInputWeights,
                                                              const std::vector<T>& cellToInputWeights,
                                                              bool hasCellToForgetWeights,
                                                              const std::vector<T>& cellToForgetWeights,
                                                              bool hasCellToOutputWeights,
                                                              const std::vector<T>& cellToOutputWeights,
                                                              bool hasInputGateBias,
                                                              const std::vector<float>& inputGateBias,
                                                              const std::vector<float>& forgetGateBias,
                                                              const std::vector<float>& cellBias,
                                                              const std::vector<float>& outputGateBias,
                                                              bool hasProjectionWeights,
                                                              const std::vector<T>& projectionWeights,
                                                              bool hasProjectionBias,
                                                              const std::vector<float>& projectionBias,
                                                              bool hasInputLayerNormWeights,
                                                              const std::vector<float>& inputLayerNormWeights,
                                                              bool hasForgetLayerNormWeights,
                                                              const std::vector<float>& forgetLayerNormWeights,
                                                              bool hasCellLayerNormWeights,
                                                              const std::vector<float>& cellLayerNormWeights,
                                                              bool hasOutputLayerNormWeights,
                                                              const std::vector<float>& outputLayerNormWeights,
                                                              tflite::ActivationFunctionType activationFunction,
                                                              float clippingThresCell,
                                                              float clippingThresProj,
                                                              bool isTimeMajor,
                                                              float quantScale,
                                                              int quantOffset = 0)
{

    std::vector<int32_t> tensorInfo0{};
    std::vector<int32_t> tensorInfoNumUnits{numUnits};
    std::vector<int32_t> tensorInfoInputSize{numUnits, inputSize};
    std::vector<int32_t> tensorInfoOutputSize{numUnits, outputSize};

    std::vector<int32_t> inputShape;
    std::vector<int32_t> outputShape;
    if (isTimeMajor)
    {
        inputShape  = {timeSize, batchSize, inputSize};
        outputShape = {timeSize, batchSize, outputSize};
    }
    else
    {
        inputShape  = {batchSize, timeSize, inputSize};
        outputShape = {batchSize, timeSize, outputSize};
    }
    std::vector<int32_t> outputStateInDimensions{batchSize, outputSize};
    std::vector<int32_t> cellStateInDimensions{batchSize, numUnits};
    std::vector<int32_t> projectionWeightDimensions{outputSize, numUnits};
    std::vector<int32_t> projectionBiasDimensions{outputSize};

    std::vector<int> operatorInputs;
    using namespace tflite;
    flatbuffers::FlatBufferBuilder                   flatBufferBuilder;
    std::vector<flatbuffers::Offset<tflite::Buffer>> buffers;
    std::vector<flatbuffers::Offset<Tensor>>         tensors;

    auto quantizationParameters =
             CreateQuantizationParameters(flatBufferBuilder,
                                          0,
                                          0,
                                          flatBufferBuilder.CreateVector<float>({1.0f}),
                                          flatBufferBuilder.CreateVector<int64_t>({0}));

    auto weightQuantizationParameters =
             CreateQuantizationParameters(flatBufferBuilder,
                                          0,
                                          0,
                                          flatBufferBuilder.CreateVector<float>({quantScale}),
                                          flatBufferBuilder.CreateVector<int64_t>({quantOffset}));

    buffers.push_back(CreateBuffer(flatBufferBuilder));
    buffers.push_back(CreateBuffer(flatBufferBuilder));
    tensors.push_back(CreateTensor(flatBufferBuilder,
                                   flatBufferBuilder.CreateVector<int32_t>(inputShape.data(),
                                                                           inputShape.size()),
                                   ::tflite::TensorType_FLOAT32,
                                   buffers.size() - 1,
                                   flatBufferBuilder.CreateString("input_0")));
    operatorInputs.push_back(tensors.size() - 1);

    if (hasInputToInputWeights)
    {
        buffers.push_back(
            CreateBuffer(flatBufferBuilder,
                         flatBufferBuilder.CreateVector(
                             reinterpret_cast<const uint8_t*>(inputToInputWeights.data()),
                             sizeof(T) * inputToInputWeights.size())));
        tensors.push_back(CreateTensor(flatBufferBuilder,
                                       flatBufferBuilder.CreateVector<int32_t>(tensorInfoInputSize.data(),
                                                                               tensorInfoInputSize.size()),
                                       tensorType,
                                       buffers.size() - 1,
                                       flatBufferBuilder.CreateString("inputToInputWeights"),
                                       weightQuantizationParameters));
        operatorInputs.push_back(tensors.size() - 1);
    }
    else
    {
        operatorInputs.push_back(kTfLiteOptionalTensor);
    }

    buffers.push_back(
        CreateBuffer(flatBufferBuilder,
                     flatBufferBuilder.CreateVector(
                         reinterpret_cast<const uint8_t*>(inputToForgetWeights.data()),
                         sizeof(T) * inputToForgetWeights.size())));
    tensors.push_back(CreateTensor(flatBufferBuilder,
                                   flatBufferBuilder.CreateVector<int32_t>(tensorInfoInputSize.data(),
                                                                           tensorInfoInputSize.size()),
                                   tensorType,
                                   buffers.size() - 1,
                                   flatBufferBuilder.CreateString("inputToForgetWeights"),
                                   weightQuantizationParameters));
    operatorInputs.push_back(tensors.size() - 1);

    buffers.push_back(
        CreateBuffer(flatBufferBuilder,
                     flatBufferBuilder.CreateVector(
                         reinterpret_cast<const uint8_t*>(inputToCellWeights.data()),
                         sizeof(T) * inputToCellWeights.size())));
    tensors.push_back(CreateTensor(flatBufferBuilder,
                                   flatBufferBuilder.CreateVector<int32_t>(tensorInfoInputSize.data(),
                                                                           tensorInfoInputSize.size()),
                                   tensorType,
                                   buffers.size() - 1,
                                   flatBufferBuilder.CreateString("inputToCellWeights"),
                                   weightQuantizationParameters));
    operatorInputs.push_back(tensors.size() - 1);

    buffers.push_back(
        CreateBuffer(flatBufferBuilder,
                     flatBufferBuilder.CreateVector(
                         reinterpret_cast<const uint8_t*>(inputToOutputWeights.data()),
                         sizeof(T) * inputToOutputWeights.size())));
    tensors.push_back(CreateTensor(flatBufferBuilder,
                                   flatBufferBuilder.CreateVector<int32_t>(tensorInfoInputSize.data(),
                                                                           tensorInfoInputSize.size()),
                                   tensorType,
                                   buffers.size() - 1,
                                   flatBufferBuilder.CreateString("inputToOutputWeights"),
                                   weightQuantizationParameters));
    operatorInputs.push_back(tensors.size() - 1);

    if (hasRecurrentToInputWeights)
    {
        buffers.push_back(CreateBuffer(
            flatBufferBuilder,
            flatBufferBuilder.CreateVector(reinterpret_cast<const uint8_t*>(recurrentToInputWeights.data()),
                                           sizeof(T) * recurrentToInputWeights.size())));
        tensors.push_back(CreateTensor(flatBufferBuilder,
                                       flatBufferBuilder.CreateVector<int32_t>(tensorInfoOutputSize.data(),
                                                                               tensorInfoOutputSize.size()),
                                       tensorType,
                                       buffers.size() - 1,
                                       flatBufferBuilder.CreateString("recurrentToInputWeights"),
                                       weightQuantizationParameters));
        operatorInputs.push_back(tensors.size() - 1);
    }
    else
    {
        operatorInputs.push_back(kTfLiteOptionalTensor);
    }

    buffers.push_back(
        CreateBuffer(flatBufferBuilder,
                     flatBufferBuilder.CreateVector(reinterpret_cast<const uint8_t*>(
                                                        recurrentToForgetWeights.data()),
                                                    sizeof(T) * recurrentToForgetWeights.size())));
    tensors.push_back(CreateTensor(flatBufferBuilder,
                                   flatBufferBuilder.CreateVector<int32_t>(tensorInfoOutputSize.data(),
                                                                           tensorInfoOutputSize.size()),
                                   tensorType,
                                   buffers.size() - 1,
                                   flatBufferBuilder.CreateString("recurrentToForgetWeights"),
                                   weightQuantizationParameters));
    operatorInputs.push_back(tensors.size() - 1);

    buffers.push_back(
        CreateBuffer(flatBufferBuilder,
                     flatBufferBuilder.CreateVector(reinterpret_cast<const uint8_t*>(
                                                        recurrentToCellWeights.data()),
                                                    sizeof(T) * recurrentToCellWeights.size())));
    tensors.push_back(CreateTensor(flatBufferBuilder,
                                   flatBufferBuilder.CreateVector<int32_t>(tensorInfoOutputSize.data(),
                                                                           tensorInfoOutputSize.size()),
                                   tensorType,
                                   buffers.size() - 1,
                                   flatBufferBuilder.CreateString("recurrentToCellWeights"),
                                   weightQuantizationParameters));
    operatorInputs.push_back(tensors.size() - 1);

    buffers.push_back(
        CreateBuffer(flatBufferBuilder,
                     flatBufferBuilder.CreateVector(reinterpret_cast<const uint8_t*>(
                                                        recurrentToOutputWeights.data()),
                                                    sizeof(T) * recurrentToOutputWeights.size())));
    tensors.push_back(CreateTensor(flatBufferBuilder,
                                   flatBufferBuilder.CreateVector<int32_t>(tensorInfoOutputSize.data(),
                                                                           tensorInfoOutputSize.size()),
                                   tensorType,
                                   buffers.size() - 1,
                                   flatBufferBuilder.CreateString("recurrentToOutputWeights"),
                                   weightQuantizationParameters));
    operatorInputs.push_back(tensors.size() - 1);

    if (hasCellToInputWeights)
    {
        buffers.push_back(
            CreateBuffer(flatBufferBuilder,
                         flatBufferBuilder.CreateVector(reinterpret_cast<const uint8_t*>(
                                                            cellToInputWeights.data()),
                                                        sizeof(T) * cellToInputWeights.size())));
        tensors.push_back(CreateTensor(flatBufferBuilder,
                                       flatBufferBuilder.CreateVector<int32_t>(tensorInfoNumUnits.data(),
                                                                               tensorInfoNumUnits.size()),
                                       tensorType,
                                       buffers.size() - 1,
                                       flatBufferBuilder.CreateString("cellToInputWeights"),
                                       weightQuantizationParameters));
        operatorInputs.push_back(tensors.size() - 1);
    }
    else
    {
        operatorInputs.push_back(kTfLiteOptionalTensor);
    }

    if (hasCellToForgetWeights)
    {
        buffers.push_back(
            CreateBuffer(flatBufferBuilder,
                         flatBufferBuilder.CreateVector(reinterpret_cast<const uint8_t*>(
                                                            cellToForgetWeights.data()),
                                                        sizeof(T) * cellToForgetWeights.size())));
        tensors.push_back(CreateTensor(flatBufferBuilder,
                                       flatBufferBuilder.CreateVector<int32_t>(tensorInfoNumUnits.data(),
                                                                               tensorInfoNumUnits.size()),
                                       tensorType,
                                       buffers.size() - 1,
                                       flatBufferBuilder.CreateString("cellToForgetWeights"),
                                       weightQuantizationParameters));
        operatorInputs.push_back(tensors.size() - 1);
    }
    else
    {
        operatorInputs.push_back(kTfLiteOptionalTensor);
    }

    if (hasCellToOutputWeights)
    {
        buffers.push_back(
            CreateBuffer(flatBufferBuilder,
                         flatBufferBuilder.CreateVector(reinterpret_cast<const uint8_t*>(
                                                            cellToOutputWeights.data()),
                                                        sizeof(T) * cellToOutputWeights.size())));
        tensors.push_back(CreateTensor(flatBufferBuilder,
                                       flatBufferBuilder.CreateVector<int32_t>(tensorInfoNumUnits.data(),
                                                                               tensorInfoNumUnits.size()),
                                       tensorType,
                                       buffers.size() - 1,
                                       flatBufferBuilder.CreateString("cellToOutputWeights"),
                                       weightQuantizationParameters));
        operatorInputs.push_back(tensors.size() - 1);
    }
    else
    {
        operatorInputs.push_back(kTfLiteOptionalTensor);
    }

    if (hasInputGateBias)
    {
        buffers.push_back(
            CreateBuffer(flatBufferBuilder,
                         flatBufferBuilder.CreateVector(reinterpret_cast<const uint8_t*>(inputGateBias.data()),
                                                        sizeof(float) * inputGateBias.size())));
        tensors.push_back(CreateTensor(flatBufferBuilder,
                                       flatBufferBuilder.CreateVector<int32_t>(tensorInfoNumUnits.data(),
                                                                               tensorInfoNumUnits.size()),
                                       ::tflite::TensorType_FLOAT32,
                                       buffers.size() - 1,
                                       flatBufferBuilder.CreateString("inputGateBias")));
        operatorInputs.push_back(tensors.size() - 1);
    }
    else
    {
        operatorInputs.push_back(kTfLiteOptionalTensor);
    }

    buffers.push_back(
        CreateBuffer(flatBufferBuilder,
                     flatBufferBuilder.CreateVector(reinterpret_cast<const uint8_t*>(forgetGateBias.data()),
                                                    sizeof(float) * forgetGateBias.size())));
    tensors.push_back(CreateTensor(flatBufferBuilder,
                                   flatBufferBuilder.CreateVector<int32_t>(tensorInfoNumUnits.data(),
                                                                           tensorInfoNumUnits.size()),
                                   ::tflite::TensorType_FLOAT32,
                                   buffers.size() - 1,
                                   flatBufferBuilder.CreateString("forgetGateBias")));
    operatorInputs.push_back(tensors.size() - 1);

    buffers.push_back(
        CreateBuffer(flatBufferBuilder,
                     flatBufferBuilder.CreateVector(reinterpret_cast<const uint8_t*>(cellBias.data()),
                                                    sizeof(float) * cellBias.size())));
    tensors.push_back(CreateTensor(flatBufferBuilder,
                                   flatBufferBuilder.CreateVector<int32_t>(tensorInfoNumUnits.data(),
                                                                           tensorInfoNumUnits.size()),
                                   ::tflite::TensorType_FLOAT32,
                                   buffers.size() - 1,
                                   flatBufferBuilder.CreateString("cellBias")));
    operatorInputs.push_back(tensors.size() - 1);

    buffers.push_back(
        CreateBuffer(flatBufferBuilder,
                     flatBufferBuilder.CreateVector(reinterpret_cast<const uint8_t*>(outputGateBias.data()),
                                                    sizeof(float) * outputGateBias.size())));
    tensors.push_back(CreateTensor(flatBufferBuilder,
                                   flatBufferBuilder.CreateVector<int32_t>(tensorInfoNumUnits.data(),
                                                                           tensorInfoNumUnits.size()),
                                   ::tflite::TensorType_FLOAT32,
                                   buffers.size() - 1,
                                   flatBufferBuilder.CreateString("outputGateBias")));
    operatorInputs.push_back(tensors.size() - 1);

    if (hasProjectionWeights)
    {
        buffers.push_back(
            CreateBuffer(flatBufferBuilder,
                         flatBufferBuilder.CreateVector(
                             reinterpret_cast<const uint8_t*>(projectionWeights.data()),
                             sizeof(T) * projectionWeights.size())));
        tensors.push_back(CreateTensor(flatBufferBuilder,
                                       flatBufferBuilder.CreateVector<int32_t>(projectionWeightDimensions.data(),
                                                                               projectionWeightDimensions.size()),
                                       tensorType,
                                       buffers.size() - 1,
                                       flatBufferBuilder.CreateString("projectionWeights"),
                                       weightQuantizationParameters));
        operatorInputs.push_back(tensors.size() - 1);
    }
    else
    {
        operatorInputs.push_back(kTfLiteOptionalTensor);
    }

    if (hasProjectionBias)
    {
        buffers.push_back(
            CreateBuffer(flatBufferBuilder,
                         flatBufferBuilder.CreateVector(
                             reinterpret_cast<const uint8_t*>(projectionBias.data()),
                             sizeof(float) * projectionBias.size())));
        tensors.push_back(CreateTensor(flatBufferBuilder,
                                       flatBufferBuilder.CreateVector<int32_t>(projectionBiasDimensions.data(),
                                                                               projectionBiasDimensions.size()),
                                       ::tflite::TensorType_FLOAT32,
                                       buffers.size() - 1,
                                       flatBufferBuilder.CreateString("projectionBias")));
        operatorInputs.push_back(tensors.size() - 1);
    }
    else
    {
        operatorInputs.push_back(kTfLiteOptionalTensor);
    }

    buffers.push_back(CreateBuffer(flatBufferBuilder));
    tensors.push_back(CreateTensor(flatBufferBuilder,
                                   flatBufferBuilder.CreateVector<int32_t>(outputStateInDimensions.data(),
                                                                           outputStateInDimensions.size()),
                                   ::tflite::TensorType_FLOAT32,
                                   buffers.size() - 1,
                                   flatBufferBuilder.CreateString("outputStateInInfo"),
                                   quantizationParameters,
                                   true));
    operatorInputs.push_back(tensors.size() - 1);

    buffers.push_back(CreateBuffer(flatBufferBuilder));
    tensors.push_back(CreateTensor(flatBufferBuilder,
                                   flatBufferBuilder.CreateVector<int32_t>(cellStateInDimensions.data(),
                                                                           cellStateInDimensions.size()),
                                   ::tflite::TensorType_FLOAT32,
                                   buffers.size() - 1,
                                   flatBufferBuilder.CreateString("cellStateInInfo"),
                                   quantizationParameters,
                                   true));
    operatorInputs.push_back(tensors.size() - 1);

    if (hasInputLayerNormWeights)
    {
        buffers.push_back(
            CreateBuffer(flatBufferBuilder,
                         flatBufferBuilder.CreateVector(
                             reinterpret_cast<const uint8_t*>(inputLayerNormWeights.data()),
                             sizeof(float) * inputLayerNormWeights.size())));
        tensors.push_back(CreateTensor(flatBufferBuilder,
                                       flatBufferBuilder.CreateVector<int32_t>(tensorInfoNumUnits.data(),
                                                                               tensorInfoNumUnits.size()),
                                       ::tflite::TensorType_FLOAT32,
                                       buffers.size() - 1,
                                       flatBufferBuilder.CreateString("inputLayerNormWeights")));
        operatorInputs.push_back(tensors.size() - 1);
    }
    else
    {
        operatorInputs.push_back(kTfLiteOptionalTensor);
    }

    if (hasForgetLayerNormWeights)
    {
        buffers.push_back(
            CreateBuffer(flatBufferBuilder,
                         flatBufferBuilder.CreateVector(
                             reinterpret_cast<const uint8_t*>(forgetLayerNormWeights.data()),
                             sizeof(float) * forgetLayerNormWeights.size())));
        tensors.push_back(CreateTensor(flatBufferBuilder,
                                       flatBufferBuilder.CreateVector<int32_t>(tensorInfoNumUnits.data(),
                                                                               tensorInfoNumUnits.size()),
                                       ::tflite::TensorType_FLOAT32,
                                       buffers.size() - 1,
                                       flatBufferBuilder.CreateString("forgetLayerNormWeights")));
        operatorInputs.push_back(tensors.size() - 1);
    }
    else
    {
        operatorInputs.push_back(kTfLiteOptionalTensor);
    }

    if (hasCellLayerNormWeights)
    {
        buffers.push_back(
            CreateBuffer(flatBufferBuilder,
                         flatBufferBuilder.CreateVector(reinterpret_cast<const uint8_t*>(
                                                            cellLayerNormWeights.data()),
                                                        sizeof(float) * cellLayerNormWeights.size())));
        tensors.push_back(CreateTensor(flatBufferBuilder,
                                       flatBufferBuilder.CreateVector<int32_t>(tensorInfoNumUnits.data(),
                                                                               tensorInfoNumUnits.size()),
                                       ::tflite::TensorType_FLOAT32,
                                       buffers.size() - 1,
                                       flatBufferBuilder.CreateString("cellLayerNormWeights")));
        operatorInputs.push_back(tensors.size() - 1);
    }
    else
    {
        operatorInputs.push_back(kTfLiteOptionalTensor);
    }

    if (hasOutputLayerNormWeights)
    {
        buffers.push_back(
            CreateBuffer(flatBufferBuilder,
                         flatBufferBuilder.CreateVector(
                             reinterpret_cast<const uint8_t*>(outputLayerNormWeights.data()),
                             sizeof(float) * outputLayerNormWeights.size())));
        tensors.push_back(CreateTensor(flatBufferBuilder,
                                       flatBufferBuilder.CreateVector<int32_t>(tensorInfoNumUnits.data(),
                                                                               tensorInfoNumUnits.size()),
                                       ::tflite::TensorType_FLOAT32,
                                       buffers.size() - 1,
                                       flatBufferBuilder.CreateString("outputLayerNormWeights")));
        operatorInputs.push_back(tensors.size() - 1);
    }
    else
    {
        operatorInputs.push_back(kTfLiteOptionalTensor);
    }
    buffers.push_back(CreateBuffer(flatBufferBuilder));
    tensors.push_back(CreateTensor(flatBufferBuilder,
                                   flatBufferBuilder.CreateVector<int32_t>(outputShape.data(),
                                                                           outputShape.size()),
                                   ::tflite::TensorType_FLOAT32,
                                   buffers.size() - 1,
                                   flatBufferBuilder.CreateString("output")));
    std::vector<int> operatorOutputs;
    operatorOutputs.push_back(tensors.size() - 1);

    // create operator
    tflite::BuiltinOptions    operatorBuiltinOptionsType = BuiltinOptions_UnidirectionalSequenceLSTMOptions;
    flatbuffers::Offset<void> operatorBuiltinOptions     =
                                  CreateUnidirectionalSequenceLSTMOptions(flatBufferBuilder,
                                                                          activationFunction,
                                                                          clippingThresCell,
                                                                          clippingThresProj,
                                                                          isTimeMajor).Union();

    flatbuffers::Offset<Operator> lstmOperator =
                                      CreateOperator(flatBufferBuilder,
                                                     0,
                                                     flatBufferBuilder.CreateVector<int32_t>(operatorInputs.data(),
                                                                                             operatorInputs.size()),
                                                     flatBufferBuilder.CreateVector<int32_t>(operatorOutputs.data(),
                                                                                             operatorOutputs.size()),
                                                     operatorBuiltinOptionsType, operatorBuiltinOptions);

    flatbuffers::Offset<SubGraph> subgraph =
                                      CreateSubGraph(flatBufferBuilder,
                                                     flatBufferBuilder.CreateVector(tensors.data(), tensors.size()),
                                                     flatBufferBuilder.CreateVector<int32_t>(operatorInputs.data(),
                                                                                             operatorInputs.size()),
                                                     flatBufferBuilder.CreateVector<int32_t>(operatorOutputs.data(),
                                                                                             operatorOutputs.size()),
                                                     flatBufferBuilder.CreateVector(&lstmOperator, 1));

    flatbuffers::Offset<flatbuffers::String> modelDescription =
                                                 flatBufferBuilder.CreateString(
                                                     "ArmnnDelegate: UnidirectionalSequenceLSTM Operator Model");
    flatbuffers::Offset<OperatorCode> operatorCode =
                                                 CreateOperatorCode(flatBufferBuilder,
                                                 tflite::BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_LSTM);

    flatbuffers::Offset<Model> flatbufferModel =
                                   CreateModel(flatBufferBuilder,
                                               TFLITE_SCHEMA_VERSION,
                                               flatBufferBuilder.CreateVector(&operatorCode, 1),
                                               flatBufferBuilder.CreateVector(&subgraph, 1),
                                               modelDescription,
                                               flatBufferBuilder.CreateVector(buffers));

    flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER);

    return std::vector<char>(flatBufferBuilder.GetBufferPointer(),
                             flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize());
}

template<typename T>
void UnidirectionalSequenceLstmTestImpl(tflite::TensorType tensorType,
                                        int32_t batchSize,
                                        int32_t timeSize,
                                        int32_t inputSize,
                                        int32_t outputSize,
                                        int32_t numUnits,
                                        bool hasInputToInputWeights,
                                        const std::vector<T>& inputToInputWeights,
                                        const std::vector<T>& inputToForgetWeights,
                                        const std::vector<T>& inputToCellWeights,
                                        const std::vector<T>& inputToOutputWeights,
                                        bool hasRecurrentToInputWeights,
                                        const std::vector<T>& recurrentToInputWeights,
                                        const std::vector<T>& recurrentToForgetWeights,
                                        const std::vector<T>& recurrentToCellWeights,
                                        const std::vector<T>& recurrentToOutputWeights,
                                        bool hasCellToInputWeights,
                                        const std::vector<T>& cellToInputWeights,
                                        bool hasCellToForgetWeights,
                                        const std::vector<T>& cellToForgetWeights,
                                        bool hasCellToOutputWeights,
                                        const std::vector<T>& cellToOutputWeights,
                                        bool hasInputGateBias,
                                        const std::vector<float>& inputGateBias,
                                        const std::vector<float>& forgetGateBias,
                                        const std::vector<float>& cellBias,
                                        const std::vector<float>& outputGateBias,
                                        bool hasProjectionWeights,
                                        const std::vector<T>& projectionWeights,
                                        bool hasProjectionBias,
                                        const std::vector<float>& projectionBias,
                                        bool hasInputLayerNormWeights,
                                        const std::vector<float>& inputLayerNormWeights,
                                        bool hasForgetLayerNormWeights,
                                        const std::vector<float>& forgetLayerNormWeights,
                                        bool hasCellLayerNormWeights,
                                        const std::vector<float>& cellLayerNormWeights,
                                        bool hasOutputLayerNormWeights,
                                        const std::vector<float>& outputLayerNormWeights,
                                        std::vector<float>& inputValues,
                                        std::vector<float>& expectedOutputValues,
                                        tflite::ActivationFunctionType activationFunction,
                                        float clippingThresCell,
                                        float clippingThresProj,
                                        bool isTimeMajor,
                                        const std::vector<armnn::BackendId>& backends = {},
                                        float quantScale = 0.1f)
{
    using namespace delegateTestInterpreter;

    std::vector<char> modelBuffer = CreateUnidirectionalSequenceLstmTfLiteModel(tensorType,
                                                                                batchSize,
                                                                                timeSize,
                                                                                inputSize,
                                                                                outputSize,
                                                                                numUnits,
                                                                                hasInputToInputWeights,
                                                                                inputToInputWeights,
                                                                                inputToForgetWeights,
                                                                                inputToCellWeights,
                                                                                inputToOutputWeights,
                                                                                hasRecurrentToInputWeights,
                                                                                recurrentToInputWeights,
                                                                                recurrentToForgetWeights,
                                                                                recurrentToCellWeights,
                                                                                recurrentToOutputWeights,
                                                                                hasCellToInputWeights,
                                                                                cellToInputWeights,
                                                                                hasCellToForgetWeights,
                                                                                cellToForgetWeights,
                                                                                hasCellToOutputWeights,
                                                                                cellToOutputWeights,
                                                                                hasInputGateBias,
                                                                                inputGateBias,
                                                                                forgetGateBias,
                                                                                cellBias,
                                                                                outputGateBias,
                                                                                hasProjectionWeights,
                                                                                projectionWeights,
                                                                                hasProjectionBias,
                                                                                projectionBias,
                                                                                hasInputLayerNormWeights,
                                                                                inputLayerNormWeights,
                                                                                hasForgetLayerNormWeights,
                                                                                forgetLayerNormWeights,
                                                                                hasCellLayerNormWeights,
                                                                                cellLayerNormWeights,
                                                                                hasOutputLayerNormWeights,
                                                                                outputLayerNormWeights,
                                                                                activationFunction,
                                                                                clippingThresCell,
                                                                                clippingThresProj,
                                                                                isTimeMajor,
                                                                                quantScale);

    std::vector<int32_t> outputShape;
    if (isTimeMajor)
    {
        outputShape = {timeSize, batchSize, outputSize};
    }
    else
    {
        outputShape = {batchSize, timeSize, outputSize};
    }

    // Setup interpreter with just TFLite Runtime.
    auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer);
    CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk);
    CHECK(tfLiteInterpreter.FillInputTensor<float>(inputValues, 0) == kTfLiteOk);
    CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk);
    std::vector<float>   tfLiteOutputValues = tfLiteInterpreter.GetOutputResult<float>(0);
    std::vector<int32_t> tfLiteOutputShape  = tfLiteInterpreter.GetOutputShape(0);

    // Setup interpreter with Arm NN Delegate applied.
    auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, CaptureAvailableBackends(backends));
    CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk);
    CHECK(armnnInterpreter.FillInputTensor<float>(inputValues, 0) == kTfLiteOk);
    CHECK(armnnInterpreter.Invoke() == kTfLiteOk);
    std::vector<float>   armnnOutputValues = armnnInterpreter.GetOutputResult<float>(0);
    std::vector<int32_t> armnnOutputShape  = armnnInterpreter.GetOutputShape(0);

    armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape);

    if (tensorType == ::tflite::TensorType_INT8)
    {
        // Allow 2% tolerance for Quantized weights
        armnnDelegate::CompareData(expectedOutputValues.data(), armnnOutputValues.data(),
                                   expectedOutputValues.size(), 2);
        armnnDelegate::CompareData(expectedOutputValues.data(), tfLiteOutputValues.data(),
                                   expectedOutputValues.size(), 2);
        armnnDelegate::CompareData(tfLiteOutputValues.data(), armnnOutputValues.data(),
                                   expectedOutputValues.size(), 2);
    }
    else
    {
        armnnDelegate::CompareOutputData<float>(tfLiteOutputValues, armnnOutputValues, expectedOutputValues);
    }

    tfLiteInterpreter.Cleanup();
    armnnInterpreter.Cleanup();
}

} // anonymous namespace