//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CLProgram.cpp: Implements the cl::Program class.
//

#include "common/unsafe_buffers.h"

#include <angle_cl.h>

#include "libANGLE/CLContext.h"
#include "libANGLE/CLDevice.h"
#include "libANGLE/CLKernel.h"
#include "libANGLE/CLObject.h"
#include "libANGLE/CLProgram.h"
#include "libANGLE/cl_utils.h"

#include <cstring>

namespace cl
{

angle::Result Program::build(cl_uint numDevices,
                             const cl_device_id *deviceList,
                             const char *options,
                             ProgramCB pfnNotify,
                             void *userData)
{
    DevicePtrs devices;
    devices.reserve(numDevices);
    while (numDevices-- != 0u)
    {
        devices.emplace_back(&(*ANGLE_UNSAFE_TODO(deviceList++))->cast<Device>());
    }
    Program *notify = nullptr;
    if (pfnNotify != nullptr)
    {
        // This program has to be retained until the notify callback is called.
        retain();
        *mCallback = CallbackData(pfnNotify, userData);
        notify     = this;
    }
    return mImpl->build(devices, options, notify);
}

angle::Result Program::compile(cl_uint numDevices,
                               const cl_device_id *deviceList,
                               const char *options,
                               cl_uint numInputHeaders,
                               const cl_program *inputHeaders,
                               const char **headerIncludeNames,
                               ProgramCB pfnNotify,
                               void *userData)
{
    DevicePtrs devices;
    devices.reserve(numDevices);
    while (numDevices-- != 0u)
    {
        devices.emplace_back(&(*ANGLE_UNSAFE_TODO(deviceList++))->cast<Device>());
    }
    ProgramPtrs programs;
    programs.reserve(numInputHeaders);
    while (numInputHeaders-- != 0u)
    {
        programs.emplace_back(&(*ANGLE_UNSAFE_TODO(inputHeaders++))->cast<Program>());
    }
    Program *notify = nullptr;
    if (pfnNotify != nullptr)
    {
        // This program has to be retained until the notify callback is called.
        retain();
        *mCallback = CallbackData(pfnNotify, userData);
        notify     = this;
    }
    return mImpl->compile(devices, options, programs, headerIncludeNames, notify);
}

angle::Result Program::getInfo(ProgramInfo name,
                               size_t valueSize,
                               void *value,
                               size_t *valueSizeRet) const
{
    std::vector<cl_device_id> devices;
    cl_uint valUInt       = 0u;
    void *valPointer      = nullptr;
    const void *copyValue = nullptr;
    size_t copySize       = 0u;

    switch (name)
    {
        case ProgramInfo::ReferenceCount:
            valUInt   = getRefCount();
            copyValue = &valUInt;
            copySize  = sizeof(valUInt);
            break;
        case ProgramInfo::Context:
            valPointer = mContext->getNative();
            copyValue  = &valPointer;
            copySize   = sizeof(valPointer);
            break;
        case ProgramInfo::NumDevices:
            valUInt   = static_cast<decltype(valUInt)>(mDevices.size());
            copyValue = &valUInt;
            copySize  = sizeof(valUInt);
            break;
        case ProgramInfo::Devices:
            devices.reserve(mDevices.size());
            for (const DevicePtr &device : mDevices)
            {
                devices.emplace_back(device->getNative());
            }
            copyValue = devices.data();
            copySize  = devices.size() * sizeof(decltype(devices)::value_type);
            break;
        case ProgramInfo::Source:
            if (!mSource.empty())
            {
                copyValue = mSource.c_str();
                copySize  = mSource.length() + 1u;
            }
            break;
        case ProgramInfo::IL:
            if (!mIL.empty())
            {
                copyValue = mIL.c_str();
                copySize  = mIL.length() + 1u;
            }
            break;
        case ProgramInfo::BinarySizes:
        case ProgramInfo::Binaries:
        case ProgramInfo::NumKernels:
        case ProgramInfo::KernelNames:
        case ProgramInfo::ScopeGlobalCtorsPresent:
        case ProgramInfo::ScopeGlobalDtorsPresent:
            return mImpl->getInfo(name, valueSize, value, valueSizeRet);
        default:
            ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
    }

    if (value != nullptr)
    {
        // CL_INVALID_VALUE if size in bytes specified by param_value_size is < size of return type
        // as described in the Program Object Queries table and param_value is not NULL.
        if (valueSize < copySize)
        {
            ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
        }
        if (copyValue != nullptr)
        {
            ANGLE_UNSAFE_TODO(std::memcpy(value, copyValue, copySize));
        }
    }
    if (valueSizeRet != nullptr)
    {
        *valueSizeRet = copySize;
    }
    return angle::Result::Continue;
}

angle::Result Program::getBuildInfo(cl_device_id device,
                                    ProgramBuildInfo name,
                                    size_t valueSize,
                                    void *value,
                                    size_t *valueSizeRet) const
{
    return mImpl->getBuildInfo(device->cast<Device>(), name, valueSize, value, valueSizeRet);
}

cl_kernel Program::createKernel(const char *kernel_name)
{
    return Object::Create<Kernel>(*this, kernel_name);
}

angle::Result Program::createKernels(cl_uint numKernels, cl_kernel *kernels, cl_uint *numKernelsRet)
{
    if (kernels == nullptr)
    {
        numKernels = 0u;
    }
    rx::CLKernelImpl::CreateFuncs createFuncs;
    ANGLE_TRY(mImpl->createKernels(numKernels, createFuncs, numKernelsRet));
    KernelPtrs krnls;
    krnls.reserve(createFuncs.size());
    while (!createFuncs.empty())
    {
        krnls.emplace_back(KernelPtr::Create(*this, createFuncs.front()));

        if (krnls.back()->mImpl == nullptr)
        {
            return angle::Result::Stop;
        }
        createFuncs.pop_front();
    }
    for (KernelPtr &kernel : krnls)
    {
        *ANGLE_UNSAFE_TODO(kernels++) = kernel.release();
    }
    return angle::Result::Continue;
}

Program::~Program() = default;

void Program::callback()
{
    CallbackData callbackData;
    mCallback->swap(callbackData);
    const ProgramCB callback = callbackData.first;
    void *const userData     = callbackData.second;
    ASSERT(callback != nullptr);
    callback(this, userData);
    // This program can be released after the callback was called.
    if (release())
    {
        delete this;
    }
}

Program::Program(Context &context, std::string &&source)
    : mContext(&context),
      mDevices(context.getDevices()),
      mNumAttachedKernels(0u),
      mImpl(nullptr),
      mSource(std::move(source))
{
    ANGLE_CL_IMPL_TRY(context.getImpl().createProgramWithSource(*this, mSource, &mImpl));
}

Program::Program(Context &context, const void *il, size_t length)
    : mContext(&context),
      mDevices(context.getDevices()),
      mIL(static_cast<const char *>(il), length),
      mNumAttachedKernels(0u),
      mImpl(nullptr)
{
    ANGLE_CL_IMPL_TRY(context.getImpl().createProgramWithIL(*this, il, length, &mImpl));
}

Program::Program(Context &context,
                 DevicePtrs &&devices,
                 const size_t *lengths,
                 const unsigned char **binaries,
                 cl_int *binaryStatus)
    : mContext(&context), mDevices(std::move(devices)), mNumAttachedKernels(0u), mImpl(nullptr)
{
    ANGLE_CL_IMPL_TRY(
        context.getImpl().createProgramWithBinary(*this, lengths, binaries, binaryStatus, &mImpl));
}

Program::Program(Context &context, DevicePtrs &&devices, const char *kernelNames)
    : mContext(&context), mDevices(std::move(devices)), mNumAttachedKernels(0u), mImpl(nullptr)
{
    ANGLE_CL_IMPL_TRY(
        context.getImpl().createProgramWithBuiltInKernels(*this, kernelNames, &mImpl));
}

Program::Program(Context &context,
                 const DevicePtrs &devices,
                 const char *options,
                 const cl::ProgramPtrs &inputPrograms,
                 ProgramCB pfnNotify,
                 void *userData)
    : mContext(&context),
      mDevices(!devices.empty() ? devices : context.getDevices()),
      mNumAttachedKernels(0u),
      mImpl(nullptr)
{
    if (pfnNotify != nullptr)
    {
        // This program has to be retained until the notify callback is called.
        retain();
        *mCallback = CallbackData(pfnNotify, userData);
    }
    else
    {
        *mCallback = CallbackData();
    }
    ANGLE_CL_IMPL_TRY(context.getImpl().linkProgram(*this, mDevices, options, inputPrograms,
                                                    pfnNotify != nullptr ? this : nullptr, &mImpl));
}

}  // namespace cl
