// 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 "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)

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) {
    wgpu::Limits limits{};
    if (!adapter_.GetLimits(&limits)) {
        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);
}

namespace {
// Returns a string representation of the wgpu::ErrorType
const char* str(wgpu::ErrorType ty) {
    switch (ty) {
        case wgpu::ErrorType::NoError:
            return "no error";
        case wgpu::ErrorType::Validation:
            return "validation";
        case wgpu::ErrorType::OutOfMemory:
            return "out of memory";
        case wgpu::ErrorType::Internal:
            return "internal";
        case wgpu::ErrorType::Unknown:
        default:
            return "unknown";
    }
}

// There's something broken with Node when attempting to write more than 65536 bytes to cout.
// Split the string up into writes of 4k chunks.
// Likely related: https://github.com/nodejs/node/issues/12921
void chunkedWrite(wgpu::StringView msg) {
    while (msg.length != 0) {
        int n;
        if (msg.length > 4096) {
            n = printf("%.4096s", msg.data);
        } else {
            n = printf("%.*s", static_cast<int>(msg.length), msg.data);
        }
        msg.data += n;
        msg.length -= n;
    }
}

}  // namespace

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;

    wgpu::Limits 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(WGPULimits::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

    for (auto [key, limit] : descriptor.requiredLimits) {
        if (!std::holds_alternative<interop::UndefinedType>(limit)) {
            promise.Reject(binding::Errors::OperationError(env, "Unknown limit \"" + key + "\""));
            return promise;
        }
    }

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

    // 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(
        [](const wgpu::Device&, ErrorType type, wgpu::StringView message) {
            printf("%s:\n", str(type));
            chunkedWrite(message);
        });

    // 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
