// Copyright 2021 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/dawn/node/binding/GPUAdapter.h"

#include <limits>
#include <memory>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

#include "dawn/utils/ComboLimits.h"
#include "src/dawn/node/binding/Converter.h"
#include "src/dawn/node/binding/Errors.h"
#include "src/dawn/node/binding/Flags.h"
#include "src/dawn/node/binding/GPUAdapterInfo.h"
#include "src/dawn/node/binding/GPUDevice.h"
#include "src/dawn/node/binding/GPUSupportedFeatures.h"
#include "src/dawn/node/binding/GPUSupportedLimits.h"
#include "src/dawn/node/binding/TogglesLoader.h"

#define FOR_EACH_LIMIT(X)                        \
    X(maxTextureDimension1D)                     \
    X(maxTextureDimension2D)                     \
    X(maxTextureDimension3D)                     \
    X(maxTextureArrayLayers)                     \
    X(maxBindGroups)                             \
    X(maxBindGroupsPlusVertexBuffers)            \
    X(maxBindingsPerBindGroup)                   \
    X(maxDynamicUniformBuffersPerPipelineLayout) \
    X(maxDynamicStorageBuffersPerPipelineLayout) \
    X(maxSampledTexturesPerShaderStage)          \
    X(maxSamplersPerShaderStage)                 \
    X(maxStorageBuffersInFragmentStage)          \
    X(maxStorageTexturesInFragmentStage)         \
    X(maxStorageBuffersInVertexStage)            \
    X(maxStorageTexturesInVertexStage)           \
    X(maxStorageBuffersPerShaderStage)           \
    X(maxStorageTexturesPerShaderStage)          \
    X(maxUniformBuffersPerShaderStage)           \
    X(maxUniformBufferBindingSize)               \
    X(maxStorageBufferBindingSize)               \
    X(minUniformBufferOffsetAlignment)           \
    X(minStorageBufferOffsetAlignment)           \
    X(maxVertexBuffers)                          \
    X(maxBufferSize)                             \
    X(maxVertexAttributes)                       \
    X(maxVertexBufferArrayStride)                \
    X(maxInterStageShaderVariables)              \
    X(maxColorAttachments)                       \
    X(maxColorAttachmentBytesPerSample)          \
    X(maxComputeWorkgroupStorageSize)            \
    X(maxComputeInvocationsPerWorkgroup)         \
    X(maxComputeWorkgroupSizeX)                  \
    X(maxComputeWorkgroupSizeY)                  \
    X(maxComputeWorkgroupSizeZ)                  \
    X(maxComputeWorkgroupsPerDimension)          \
    X(maxImmediateSize)

namespace wgpu::binding {

////////////////////////////////////////////////////////////////////////////////
// wgpu::bindings::GPUAdapter
// TODO(crbug.com/dawn/1133): This is a stub implementation. Properly implement.
////////////////////////////////////////////////////////////////////////////////
GPUAdapter::GPUAdapter(wgpu::Adapter adapter,
                       const Flags& flags,
                       std::shared_ptr<AsyncRunner> async)
    : adapter_(adapter), flags_(flags), async_(async) {}

interop::Interface<interop::GPUSupportedFeatures> GPUAdapter::getFeatures(Napi::Env env) {
    wgpu::SupportedFeatures features{};
    adapter_.GetFeatures(&features);
    return interop::GPUSupportedFeatures::Create<GPUSupportedFeatures>(env, env, features);
}

interop::Interface<interop::GPUSupportedLimits> GPUAdapter::getLimits(Napi::Env env) {
    dawn::utils::ComboLimits limits;
    if (!adapter_.GetLimits(limits.GetLinked())) {
        Napi::Error::New(env, "failed to get adapter limits").ThrowAsJavaScriptException();
    }

    return interop::GPUSupportedLimits::Create<GPUSupportedLimits>(env, limits);
}

interop::Interface<interop::GPUAdapterInfo> GPUAdapter::getInfo(Napi::Env env) {
    wgpu::AdapterInfo info = {};

    wgpu::AdapterPropertiesSubgroupMatrixConfigs subgroupMatrixConfigs;
    if (adapter_.HasFeature(FeatureName::ChromiumExperimentalSubgroupMatrix)) {
        info.nextInChain = &subgroupMatrixConfigs;
    }

    adapter_.GetInfo(&info);

    return interop::GPUAdapterInfo::Create<GPUAdapterInfo>(env, info);
}

interop::Promise<interop::Interface<interop::GPUDevice>> GPUAdapter::requestDevice(
    Napi::Env env,
    interop::GPUDeviceDescriptor descriptor) {
    wgpu::DeviceDescriptor desc{};  // TODO(crbug.com/dawn/1133): Fill in.

    Converter conv(env);
    std::vector<wgpu::FeatureName> requiredFeatures;
    for (auto required : descriptor.requiredFeatures) {
        wgpu::FeatureName feature;

        // requiredFeatures is a "sequence<GPUFeatureName>" so a Javascript exception should be
        // thrown if one of the strings isn't one of the known features.
        if (!conv(feature, required)) {
            Napi::TypeError::New(env, "Unknown GPUFeatureName.").ThrowAsJavaScriptException();
            return {env, interop::kUnusedPromise};
        }

        requiredFeatures.emplace_back(feature);
    }
    if (!conv(desc.label, descriptor.label)) {
        return {env, interop::kUnusedPromise};
    }

    auto ctx = std::make_unique<AsyncContext<interop::Interface<interop::GPUDevice>>>(
        env, PROMISE_INFO, async_);
    auto promise = ctx->promise;

    dawn::utils::ComboLimits limits;
#define COPY_LIMIT(LIMIT)                                                                        \
    if (descriptor.requiredLimits.count(#LIMIT)) {                                               \
        auto jsLimitVariant = descriptor.requiredLimits[#LIMIT];                                 \
        if (!std::holds_alternative<interop::UndefinedType>(jsLimitVariant)) {                   \
            using DawnLimitType = decltype(dawn::utils::ComboLimits::LIMIT);                     \
            DawnLimitType* dawnLimit = &limits.LIMIT;                                            \
            uint64_t jsLimit = std::get<interop::GPUSize64>(jsLimitVariant);                     \
            if (jsLimit > std::numeric_limits<DawnLimitType>::max() - 1) {                       \
                promise.Reject(                                                                  \
                    binding::Errors::OperationError(env, "Limit \"" #LIMIT "\" out of range.")); \
                return promise;                                                                  \
            }                                                                                    \
            *dawnLimit = jsLimit;                                                                \
        }                                                                                        \
        descriptor.requiredLimits.erase(#LIMIT);                                                 \
    }
    FOR_EACH_LIMIT(COPY_LIMIT)
#undef COPY_LIMIT

    // Must throw a OperationError if the required limit is not supported by the adapter
    for (auto [key, limit] : descriptor.requiredLimits) {
        if (!std::holds_alternative<interop::UndefinedType>(limit)) {
            promise.Reject(binding::Errors::OperationError(env, "Unknown limit \"" + key + "\""));
            return promise;
        }
    }

    // Must throw a TypeError if the required feature is not supported by the adapter
    for (auto& f : requiredFeatures) {
        if (!adapter_.HasFeature(f)) {
            promise.Reject(Napi::TypeError::New(
                ctx->env, "Unsupported feature: " + std::to_string(static_cast<uint32_t>(f))));
            return promise;
        }
    }

    desc.requiredFeatureCount = requiredFeatures.size();
    desc.requiredFeatures = requiredFeatures.data();
    desc.requiredLimits = limits.GetLinked();

    // Set the device callbacks.
    using DeviceLostContext = AsyncContext<interop::Interface<interop::GPUDeviceLostInfo>>;
    auto device_lost_ctx = new DeviceLostContext(env, PROMISE_INFO, async_);
    auto device_lost_promise = device_lost_ctx->promise;
    desc.SetDeviceLostCallback(
        wgpu::CallbackMode::AllowSpontaneous,
        [](const wgpu::Device&, wgpu::DeviceLostReason reason, wgpu::StringView message,
           DeviceLostContext* device_lost_ctx) {
            std::unique_ptr<DeviceLostContext> ctx(device_lost_ctx);
            auto r = interop::GPUDeviceLostReason::kDestroyed;
            switch (reason) {
                case wgpu::DeviceLostReason::Destroyed:
                case wgpu::DeviceLostReason::CallbackCancelled:
                    r = interop::GPUDeviceLostReason::kDestroyed;
                    break;
                case wgpu::DeviceLostReason::FailedCreation:
                case wgpu::DeviceLostReason::Unknown:
                    r = interop::GPUDeviceLostReason::kUnknown;
                    break;
            }
            if (ctx->promise.GetState() == interop::PromiseState::Pending) {
                ctx->promise.Resolve(interop::GPUDeviceLostInfo::Create<GPUDeviceLostInfo>(
                    ctx->env, r, std::string(message)));
            }
        },
        device_lost_ctx);
    desc.SetUncapturedErrorCallback(GPUDevice::handleUncapturedErrorCallback);

    // Propagate enabled/disabled dawn features
    TogglesLoader togglesLoader(flags_);
    DawnTogglesDescriptor deviceTogglesDesc = togglesLoader.GetDescriptor();
    desc.nextInChain = &deviceTogglesDesc;

    std::unique_ptr<GPUDevice> gpu_device;
    adapter_.RequestDevice(
        &desc, wgpu::CallbackMode::AllowSpontaneous,
        [ctx = std::move(ctx), desc, device_lost_promise, this, &gpu_device](
            wgpu::RequestDeviceStatus status, wgpu::Device wgpu_device, wgpu::StringView message) {
            switch (status) {
                case wgpu::RequestDeviceStatus::Success:
                    gpu_device = std::make_unique<GPUDevice>(ctx->env, desc, wgpu_device,
                                                             device_lost_promise, async_);
                    if (!valid_) {
                        gpu_device->ForceLoss(wgpu::DeviceLostReason::Unknown,
                                              "Device was marked as lost due to a stale adapter.");
                    }
                    valid_ = false;

                    ctx->promise.Resolve(interop::GPUDevice::Bind(ctx->env, std::move(gpu_device)));
                    break;
                default:
                    ctx->promise.Reject(Errors::OperationError(ctx->env, std::string(message)));
                    break;
            }
        });
    return promise;
}

}  // namespace wgpu::binding
