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

#pragma once

#include "BaseIterator.hpp"
#include <backendsCommon/CpuTensorHandle.hpp>

namespace
{

// Helper functions ported from the Android code base
// Refer to: android/external/tensorflow/tensorflow/contrib/lite/kernels/internal/reference/portable_tensor_utils.cc

void MatrixBatchVectorMultiplyAccumulate(armnn::Decoder<float>& matrix,
                                         uint32_t mRows,
                                         uint32_t mCols,
                                         armnn::Decoder<float>& vector,
                                         uint32_t nBatch,
                                         armnn::Encoder<float>& outResult)
{
    for (uint32_t b = 0; b < nBatch; b++)
    {
        for (uint32_t r = 0; r < mRows; r++)
        {
            vector += b * mCols;
            for (uint32_t c = 0; c < mCols; c++)
            {
                outResult.Set(outResult.Get() + matrix.Get() * vector.Get());
                ++matrix;
                ++vector;
            }
            outResult += 1;
            vector -= (b+1) * mCols;
        }
        matrix -= (mRows * mCols);
    }
    outResult -= (mRows * nBatch);
}

void VectorBatchVectorAssign(armnn::Decoder<float>& vector,
                             uint32_t vSize,
                             uint32_t nBatch,
                             armnn::Encoder<float>& outBatchVector)
{
    for (uint32_t b = 0; b < nBatch; b++)
    {
        for (uint32_t v = 0; v < vSize; v++)
        {
            outBatchVector.Set(vector.Get());
            ++outBatchVector;
            ++vector;
        }
        vector -= vSize;
    }
    outBatchVector -= (nBatch * vSize);
}

void VectorBatchVectorCwiseProductAccumulate(armnn::Decoder<float>& vector,
                                             uint32_t vSize,
                                             armnn::Decoder<float>& batchVector,
                                             uint32_t nBatch,
                                             armnn::Encoder<float>& outResult)
{
    for (uint32_t b = 0; b < nBatch; b++)
    {
        for (uint32_t v = 0; v < vSize; v++)
        {
            outResult.Set(outResult.Get() + vector.Get() * batchVector.Get());
            ++outResult;
            ++vector;
            ++batchVector;
        }
        vector -= vSize;
    }
    batchVector -= vSize * nBatch;
    outResult -= vSize * nBatch;
}

void Sub1Vector(armnn::Decoder<float>& vector,
                uint32_t vSize,
                armnn::Encoder<float>& result)
{
    for (uint32_t v = 0; v < vSize; v++)
    {
        result.Set(1.0f - vector.Get());
        ++vector;
        ++result;
    }
    vector -= vSize;
    result -= vSize;
}

void VectorVectorCwiseProduct(armnn::Decoder<float>& vector1,
                              armnn::Decoder<float>& vector2,
                              uint32_t vSize,
                              armnn::Encoder<float>& outResult)
{
    for (uint32_t v = 0; v < vSize; v++)
    {
        outResult.Set(vector1.Get() * vector2.Get());
        ++outResult;
        ++vector1;
        ++vector2;
    }
    outResult -= vSize;
    vector1 -= vSize;
    vector2 -= vSize;
}

void VectorVectorCwiseProductAccumulate(armnn::Decoder<float>& vector1,
                                        armnn::Decoder<float>& vector2,
                                        uint32_t vSize,
                                        armnn::Encoder<float>& outResult)
{
    for (uint32_t v = 0; v < vSize; v++)
    {
        outResult.Set(outResult.Get() + vector1.Get() * vector2.Get());
        ++outResult;
        ++vector1;
        ++vector2;
    }
    outResult -= vSize;
    vector1 -= vSize;
    vector2 -= vSize;
}

float Clip(float f,
           float absLimit)
{
    float result = (absLimit < f) ? absLimit : f;
    result = (-absLimit > result) ? -absLimit : result;
    return result;
}

void ClipVector(armnn::Decoder<float>& vector,
                uint32_t vSize,
                float absLimit,
                armnn::Encoder<float>& outResult)
{
    for (uint32_t v = 0; v < vSize; v++)
    {
        outResult.Set(Clip(vector.Get(), absLimit));
        ++vector;
        ++outResult;
    }
    vector -= vSize;
    outResult -= vSize;
}

void CopyVector(armnn::Decoder<float>& vector,
                uint32_t vSize,
                armnn::Encoder<float>& outResult)
{
    for (uint32_t v = 0; v < vSize; v++)
    {
        outResult.Set(vector.Get());
        ++outResult;
        ++vector;
    }
    outResult -= vSize;
    vector -= vSize;
}

void SetActivationParameters(uint32_t activation,
                             armnn::ActivationFunction& outArmnnActivation,
                             float& outA,
                             float& outB)
{
    switch (activation)
    {
    case 0: // None
        outA = 0;
        outB = 0;
        return;

    case 1: // Relu
        outArmnnActivation = armnn::ActivationFunction::ReLu;
        outA = 0;
        outB = 0;
        return;

    case 3: // Relu6
        outArmnnActivation = armnn::ActivationFunction::BoundedReLu;
        outA = 6;
        outB = 0;
        return;

    case 4: // Tanh
        outArmnnActivation = armnn::ActivationFunction::TanH;
        outA = 1;
        outB = 1;
        return;

    case 6: // Sigmoid
        outArmnnActivation = armnn::ActivationFunction::Sigmoid;
        outA = 0;
        outB = 0;
        return;

    default:
        throw armnn::Exception("Unsupported activation function: " + std::to_string(activation));
    }
}

std::unique_ptr<armnn::ScopedCpuTensorHandle> AssignScopedCpuTensorHandle(const armnn::ConstCpuTensorHandle* ptr)
{
    if (!ptr)
    {
        return nullptr;
    }

    return std::make_unique<armnn::ScopedCpuTensorHandle>(*ptr);
}

} // anonymous namespace
