/*
 * Copyright (c) 2021 Arm Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include "src/gpu/cl/operators/ClConcatenate.h"

#include "arm_compute/core/Error.h"
#include "arm_compute/core/TensorInfo.h"
#include "arm_compute/core/Types.h"
#include "arm_compute/core/utils/misc/ShapeCalculator.h"
#include "arm_compute/runtime/CL/CLScheduler.h"

#include "src/common/utils/Log.h"
#include "src/core/helpers/AutoConfiguration.h"
#include "src/gpu/cl/kernels/ClBatchConcatenateKernel.h"
#include "src/gpu/cl/kernels/ClDepthConcatenateKernel.h"
#include "src/gpu/cl/kernels/ClHeightConcatenateKernel.h"
#include "src/gpu/cl/kernels/ClWidthConcatenate2TensorsKernel.h"
#include "src/gpu/cl/kernels/ClWidthConcatenate4TensorsKernel.h"
#include "src/gpu/cl/kernels/ClWidthConcatenateKernel.h"

namespace arm_compute
{
namespace opencl
{
void ClConcatenate::configure(const CLCompileContext           &compile_context,
                              const std::vector<ITensorInfo *> &src_vector,
                              ITensorInfo                      *dst,
                              size_t                            axis)
{
    ARM_COMPUTE_ERROR_ON(dst == nullptr);
    ARM_COMPUTE_LOG_PARAMS(src_vector, dst, axis);
    _axis       = axis;
    _num_inputs = src_vector.size();

    TensorShape dst_shape = arm_compute::misc::shape_calculator::calculate_concatenate_shape(src_vector, _axis);
    std::vector<const ITensorInfo *> const_src_vector(src_vector.size());
    std::transform(src_vector.begin(), src_vector.end(), const_src_vector.begin(),
                   [](ITensorInfo *t)
                   {
                       ARM_COMPUTE_ERROR_ON_NULLPTR(t);
                       return t;
                   });

    // dst auto inizialitation if not yet initialized
    auto_init_if_empty(*dst, dst_shape, 1, src_vector[0]->data_type());
    ARM_COMPUTE_ERROR_THROW_ON(ClConcatenate::validate(const_src_vector, dst, axis));

    unsigned int offset = 0;
    switch (_axis)
    {
        case Window::DimX:
        {
            switch (_num_inputs)
            {
                case 2:
                {
                    // Configure WidthConcatenate2Tensors kernel
                    auto kernel = std::make_unique<kernels::ClWidthConcatenate2TensorsKernel>();
                    kernel->configure(compile_context, src_vector.at(0), src_vector.at(1), dst);
                    _concat_kernels.emplace_back(std::move(kernel));
                    break;
                }
                case 4:
                {
                    // Configure WidthConcatenate4Tensors kernel
                    auto kernel = std::make_unique<kernels::ClWidthConcatenate4TensorsKernel>();
                    kernel->configure(compile_context, src_vector.at(0), src_vector.at(1), src_vector.at(2),
                                      src_vector.at(3), dst);
                    _concat_kernels.emplace_back(std::move(kernel));
                    break;
                }
                default:
                {
                    // Configure generic case WidthConcatenate kernels
                    for (unsigned int i = 0; i < _num_inputs; ++i)
                    {
                        auto kernel = std::make_unique<kernels::ClWidthConcatenateKernel>();
                        kernel->configure(compile_context, src_vector.at(i), offset, dst);
                        offset += src_vector.at(i)->dimension(_axis);
                        _concat_kernels.emplace_back(std::move(kernel));
                    }
                    break;
                }
            }
            break;
        }
        case Window::DimY:
        {
            for (unsigned int i = 0; i < _num_inputs; ++i)
            {
                auto kernel = std::make_unique<kernels::ClHeightConcatenateKernel>();
                kernel->configure(compile_context, src_vector.at(i), offset, dst);
                offset += src_vector.at(i)->dimension(_axis);
                _concat_kernels.emplace_back(std::move(kernel));
            }
            break;
        }
        case Window::DimZ:
        {
            for (unsigned int i = 0; i < _num_inputs; ++i)
            {
                auto kernel = std::make_unique<kernels::ClDepthConcatenateKernel>();
                kernel->configure(compile_context, src_vector.at(i), offset, dst);
                offset += src_vector.at(i)->dimension(_axis);
                _concat_kernels.emplace_back(std::move(kernel));
            }
            break;
        }
        case 3:
        {
            for (unsigned int i = 0; i < _num_inputs; ++i)
            {
                auto kernel = std::make_unique<kernels::ClBatchConcatenateKernel>();
                kernel->configure(compile_context, src_vector.at(i), offset, dst);
                offset += src_vector.at(i)->dimension(_axis);
                _concat_kernels.emplace_back(std::move(kernel));
            }
            break;
        }
        default:
            ARM_COMPUTE_ERROR("Axis not supported");
    }
}

Status ClConcatenate::validate(const std::vector<const ITensorInfo *> &src_vector, const ITensorInfo *dst, size_t axis)
{
    ARM_COMPUTE_RETURN_ERROR_ON(dst == nullptr);
    const unsigned int num_inputs = src_vector.size();

    ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(dst);
    ARM_COMPUTE_RETURN_ERROR_ON(num_inputs < 2);

    unsigned int offset = 0;
    switch (axis)
    {
        case Window::DimX:
        {
            switch (num_inputs)
            {
                case 2:
                    // Validate WidthConcatenate2Tensors kernels if there are 2 inputs
                    ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src_vector[0], src_vector[1]);
                    ARM_COMPUTE_RETURN_ON_ERROR(
                        kernels::ClWidthConcatenate2TensorsKernel::validate(src_vector[0], src_vector[1], dst));
                    break;
                case 4:
                    // Validate WidthConcatenate4Tensors kernels if there are 4 inputs
                    ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src_vector[0], src_vector[1], src_vector[2], src_vector[3]);
                    ARM_COMPUTE_RETURN_ON_ERROR(kernels::ClWidthConcatenate4TensorsKernel::validate(
                        src_vector[0], src_vector[1], src_vector[2], src_vector[3], dst));
                    break;
                default:
                    // Validate generic case of WidthConcatenate kernel
                    for (const auto &src : src_vector)
                    {
                        ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src);
                        ARM_COMPUTE_RETURN_ON_ERROR(kernels::ClWidthConcatenateKernel::validate(src, offset, dst));
                        offset += src->dimension(axis);
                    }
                    break;
            }
            break;
        }
        case Window::DimY:
        {
            for (const auto &src : src_vector)
            {
                ARM_COMPUTE_RETURN_ON_ERROR(kernels::ClHeightConcatenateKernel::validate(src, offset, dst));
                offset += src->dimension(axis);
            }
            break;
        }
        case Window::DimZ:
        {
            for (const auto &src : src_vector)
            {
                ARM_COMPUTE_RETURN_ON_ERROR(kernels::ClDepthConcatenateKernel::validate(src, offset, dst));
                offset += src->dimension(axis);
            }
            break;
        }
        case 3:
        {
            for (const auto &src : src_vector)
            {
                ARM_COMPUTE_RETURN_ON_ERROR(kernels::ClBatchConcatenateKernel::validate(src, offset, dst));
                offset += src->dimension(axis);
            }
            break;
        }
        default:
            ARM_COMPUTE_ERROR("Axis not supported");
    }

    if (dst->total_size() != 0)
    {
        TensorShape dst_shape = arm_compute::misc::shape_calculator::calculate_concatenate_shape(src_vector, axis);
        ARM_COMPUTE_RETURN_ERROR_ON(dst_shape.total_size() != dst->tensor_shape().total_size());
    }

    return Status{};
}

void ClConcatenate::run(ITensorPack &tensors)
{
    if (tensors.empty())
    {
        ARM_COMPUTE_ERROR("No inputs provided");
    }

    if (static_cast<int>(tensors.size()) - 1 != static_cast<int>(_num_inputs))
    {
        ARM_COMPUTE_ERROR("Configured with different number of inputs");
    }

    if (_axis == Window::DimX && (_num_inputs == 2 || _num_inputs == 4))
    {
        ARM_COMPUTE_ERROR_ON(_concat_kernels.empty());
        CLScheduler::get().enqueue_op(*_concat_kernels.at(0), tensors, true);
    }
    else
    {
        int i = 0;
        for (auto &k : _concat_kernels)
        {
            ITensorPack pack;
            pack.add_tensor(TensorType::ACL_SRC, tensors.get_const_tensor(ACL_SRC_VEC + i));
            pack.add_tensor(TensorType::ACL_DST, tensors.get_tensor(ACL_DST));
            CLScheduler::get().enqueue_op(*k, pack, true);
            ++i;
        }
    }
}
} // namespace opencl
} // namespace arm_compute
