/*
 * Copyright (c) 2021,2023 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 "arm_compute/AclEntrypoints.h"
#include "arm_compute/core/Error.h"

#include "src/common/IContext.h"
#include "src/common/utils/Macros.h"
#include "src/common/utils/Validate.h"

#ifdef ARM_COMPUTE_CPU_ENABLED
#include "src/cpu/CpuContext.h"
#endif /* ARM_COMPUTE_CPU_ENABLED */

#ifdef ARM_COMPUTE_OPENCL_ENABLED
#include "src/gpu/cl/ClContext.h"
#endif /* ARM_COMPUTE_OPENCL_ENABLED */

namespace
{
template <typename ContextType>
arm_compute::IContext *create_backend_ctx(const AclContextOptions *options)
{
    return new (std::nothrow) ContextType(options);
}

bool is_target_valid(AclTarget target)
{
    return arm_compute::utils::is_in(target, {AclCpu, AclGpuOcl});
}

bool are_context_options_valid(const AclContextOptions *options)
{
    ARM_COMPUTE_ASSERT_NOT_NULLPTR(options);
    return arm_compute::utils::is_in(options->mode, {AclPreferFastRerun, AclPreferFastStart});
}

arm_compute::IContext *create_context(AclTarget target, const AclContextOptions *options)
{
    ARM_COMPUTE_UNUSED(options);

    switch (target)
    {
#ifdef ARM_COMPUTE_CPU_ENABLED
        case AclCpu:
            return create_backend_ctx<arm_compute::cpu::CpuContext>(options);
#endif /* ARM_COMPUTE_CPU_ENABLED */
#ifdef ARM_COMPUTE_OPENCL_ENABLED
        case AclGpuOcl:
            return create_backend_ctx<arm_compute::gpu::opencl::ClContext>(options);
#endif /* ARM_COMPUTE_OPENCL_ENABLED */
        default:
            return nullptr;
    }
    return nullptr;
}
} // namespace

extern "C" AclStatus AclCreateContext(AclContext *external_ctx, AclTarget target, const AclContextOptions *options)
{
    if (!is_target_valid(target))
    {
        ARM_COMPUTE_LOG_ERROR_WITH_FUNCNAME_ACL("Target is invalid!");
        return AclUnsupportedTarget;
    }

    if (options != nullptr && !are_context_options_valid(options))
    {
        ARM_COMPUTE_LOG_ERROR_WITH_FUNCNAME_ACL("Context options are invalid!");
        return AclInvalidArgument;
    }

    auto ctx = create_context(target, options);
    if (ctx == nullptr)
    {
        ARM_COMPUTE_LOG_ERROR_WITH_FUNCNAME_ACL("Couldn't allocate internal resources for context creation!");
        return AclOutOfMemory;
    }
    *external_ctx = ctx;

    return AclSuccess;
}

extern "C" AclStatus AclDestroyContext(AclContext external_ctx)
{
    using namespace arm_compute;

    IContext *ctx = get_internal(external_ctx);

    StatusCode status = detail::validate_internal_context(ctx);
    ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);

    if (ctx->refcount() != 0)
    {
        ARM_COMPUTE_LOG_ERROR_WITH_FUNCNAME_ACL("Context has references on it that haven't been released!");
        // TODO: Fix the refcount with callback when reaches 0
    }

    delete ctx;

    return utils::as_cenum<AclStatus>(status);
}
