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

#include "Reduce.hpp"

#include <armnn/utility/NumericCast.hpp>

#include <backendsCommon/WorkloadData.hpp>

#include <cmath>
#include <cstddef>
#include <functional>
#include <limits>

namespace armnn
{

bool NextIndex(const unsigned int numDims, const armnn::TensorShape& dims, std::vector<unsigned int>& current)
{
    unsigned int carry = 1;

    for (unsigned int idx = numDims; idx-- > 0; )
    {
        unsigned int current_val = current[idx] + carry;
        if (dims[idx] == current_val)
        {
            current[idx] = 0;
        }
        else
        {
            current[idx] = current_val;
            carry = 0;
            break;
        }
    }
    return (carry == 0);
}

unsigned int ReducedOutputOffset(const unsigned int numDims,
                                 const armnn::TensorShape& dims,
                                 std::vector<unsigned int>& index,
                                 const unsigned int numAxis,
                                 const std::vector<unsigned int>& axis)
{
    unsigned int offset = 0;
    for (unsigned int idx = 0; idx < numDims; ++idx)
    {
        bool isAxis = false;
        if (!axis.empty())
        {
            for (unsigned int axisIdx = 0; axisIdx < numAxis; ++axisIdx)
            {
                if (idx == axis[axisIdx])
                {
                    isAxis = true;
                    break;
                }
            }
        }
        if (!isAxis)
        {
            offset = offset * dims[idx] + index[idx];
        }
    }
    return offset;
}


void Reduce(const TensorInfo& inputInfo,
            const TensorInfo& outputInfo,
            Decoder<float>& input,
            Encoder<float>& output,
            const std::vector<uint32_t> axis,
            const ReduceOperation reduceOperation)
{
    armnn::TensorShape inputDims = inputInfo.GetShape();
    unsigned int inputNumDims    = inputInfo.GetNumDimensions();
    unsigned int numOutputs      = outputInfo.GetNumElements();

    // Initialise temp output
    std::vector<float> tempOut(numOutputs);
    switch(reduceOperation)
    {
        case ReduceOperation::Mean:
        case ReduceOperation::Sum:
            std::fill(tempOut.begin(), tempOut.end(), 0.0f);
            break;
        case ReduceOperation::Max:
            std::fill(tempOut.begin(), tempOut.end(), -1 * std::numeric_limits<float>::max());
            break;
        case ReduceOperation::Min:
            std::fill(tempOut.begin(), tempOut.end(), std::numeric_limits<float>::max());
            break;
        default:
            throw armnn::InvalidArgumentException("Unknown reduce method: " +
                std::to_string(static_cast<int>(reduceOperation)));
    }

    // Initialise temp index
    std::vector<unsigned int> tempIndex(inputNumDims, 0);

    std::vector<unsigned int> resolvedAxis = axis;
    if (resolvedAxis.empty())
    {
        for (unsigned int idx = 0; idx < inputNumDims; ++idx)
        {
            resolvedAxis.push_back(idx);
        }
    }
    auto numResolvedAxis = armnn::numeric_cast<unsigned int>(resolvedAxis.size());

    // Iterates through input_data and operates over the reduced axis
    for (bool hasNext = true; hasNext; hasNext = NextIndex(inputNumDims, inputDims, tempIndex))
    {
        unsigned int inputOffset = ReducedOutputOffset(inputNumDims, inputDims, tempIndex, 0, {});
        unsigned int outputOffset = ReducedOutputOffset(inputNumDims, inputDims, tempIndex,
                                                        numResolvedAxis, resolvedAxis);
        input[inputOffset];
        auto inputValue = input.Get();
        if (reduceOperation == ReduceOperation::Max)
        {
            if (inputValue > tempOut[outputOffset])
            {
                tempOut[outputOffset] = inputValue;
            }
        }
        else if (reduceOperation == ReduceOperation::Min)
        {
            if (inputValue < tempOut[outputOffset])
            {
                tempOut[outputOffset] = inputValue;
            }
        }
        else
        {
            tempOut[outputOffset] += inputValue;
        }
    }

    // Takes average by num of elements added to get MEAN
    size_t numElementsInAxis = 1;
    for (unsigned int idx = 0; idx < numResolvedAxis; ++idx)
    {
        unsigned int current = inputDims[resolvedAxis[idx]];
        ARMNN_ASSERT(armnn::numeric_cast<float>(current) <
                     (std::numeric_limits<float>::max() / armnn::numeric_cast<float>(numElementsInAxis)));
        numElementsInAxis *= current;
    }

    for (unsigned int idx = 0; idx < numOutputs; ++idx)
    {
        output[idx];
        if (reduceOperation == ReduceOperation::Mean)
        {
            if (numElementsInAxis > 0)
            {
                output.Set(tempOut[idx] / armnn::numeric_cast<float>(numElementsInAxis));
            }
        }
        else
        {
            output.Set(tempOut[idx]);
        }
    }
}

} //namespace armnn