// Copyright 2021 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "src/dawn_node/binding/GPUDevice.h"

#include <memory>

#include "src/dawn_node/binding/Converter.h"
#include "src/dawn_node/binding/Errors.h"
#include "src/dawn_node/binding/GPUBindGroup.h"
#include "src/dawn_node/binding/GPUBindGroupLayout.h"
#include "src/dawn_node/binding/GPUBuffer.h"
#include "src/dawn_node/binding/GPUCommandBuffer.h"
#include "src/dawn_node/binding/GPUCommandEncoder.h"
#include "src/dawn_node/binding/GPUComputePipeline.h"
#include "src/dawn_node/binding/GPUPipelineLayout.h"
#include "src/dawn_node/binding/GPUQuerySet.h"
#include "src/dawn_node/binding/GPUQueue.h"
#include "src/dawn_node/binding/GPURenderBundleEncoder.h"
#include "src/dawn_node/binding/GPURenderPipeline.h"
#include "src/dawn_node/binding/GPUSampler.h"
#include "src/dawn_node/binding/GPUShaderModule.h"
#include "src/dawn_node/binding/GPUSupportedLimits.h"
#include "src/dawn_node/binding/GPUTexture.h"
#include "src/dawn_node/utils/Debug.h"

namespace wgpu { namespace binding {

    namespace {

        class DeviceLostInfo : public interop::GPUDeviceLostInfo {
          public:
            DeviceLostInfo(interop::GPUDeviceLostReason reason, std::string message)
                : reason_(reason), message_(message) {
            }
            std::variant<interop::GPUDeviceLostReason> getReason(Napi::Env env) override {
                return reason_;
            }
            std::string getMessage(Napi::Env) override {
                return message_;
            }

          private:
            interop::GPUDeviceLostReason reason_;
            std::string message_;
        };

        class OOMError : public interop::GPUOutOfMemoryError {};
        class ValidationError : public interop::GPUValidationError {
          public:
            ValidationError(std::string message) : message_(std::move(message)) {
            }

            std::string getMessage(Napi::Env) override {
                return message_;
            };

          private:
            std::string message_;
        };

    }  // namespace

    ////////////////////////////////////////////////////////////////////////////////
    // wgpu::bindings::GPUDevice
    ////////////////////////////////////////////////////////////////////////////////
    GPUDevice::GPUDevice(Napi::Env env, wgpu::Device device)
        : env_(env), device_(device), async_(std::make_shared<AsyncRunner>(env, device)) {
        device_.SetLoggingCallback(
            [](WGPULoggingType type, char const* message, void* userdata) {
                std::cout << type << ": " << message << std::endl;
            },
            nullptr);
        device_.SetUncapturedErrorCallback(
            [](WGPUErrorType type, char const* message, void* userdata) {
                std::cout << type << ": " << message << std::endl;
            },
            nullptr);

        device_.SetDeviceLostCallback(
            [](WGPUDeviceLostReason reason, char const* message, void* userdata) {
                auto r = interop::GPUDeviceLostReason::kDestroyed;
                switch (reason) {
                    case WGPUDeviceLostReason_Destroyed:
                        r = interop::GPUDeviceLostReason::kDestroyed;
                        break;
                }
                auto* self = static_cast<GPUDevice*>(userdata);
                for (auto promise : self->lost_promises_) {
                    promise.Resolve(
                        interop::GPUDeviceLostInfo::Create<DeviceLostInfo>(self->env_, r, message));
                }
            },
            this);
    }

    GPUDevice::~GPUDevice() {
    }

    interop::Interface<interop::GPUSupportedFeatures> GPUDevice::getFeatures(Napi::Env env) {
        class Features : public interop::GPUSupportedFeatures {
          public:
            bool has(Napi::Env, std::string feature) override {
                UNIMPLEMENTED();
            }
        };
        return interop::GPUSupportedFeatures::Create<Features>(env);
    }

    interop::Interface<interop::GPUSupportedLimits> GPUDevice::getLimits(Napi::Env env) {
        return interop::GPUSupportedLimits::Create<GPUSupportedLimits>(env);
    }

    interop::Interface<interop::GPUQueue> GPUDevice::getQueue(Napi::Env env) {
        // TODO(crbug.com/dawn/1144): Should probably return the same Queue JS object.
        return interop::GPUQueue::Create<GPUQueue>(env, device_.GetQueue(), async_);
    }

    void GPUDevice::destroy(Napi::Env) {
        device_.Release();
    }

    interop::Interface<interop::GPUBuffer> GPUDevice::createBuffer(
        Napi::Env env,
        interop::GPUBufferDescriptor descriptor) {
        Converter conv(env);

        wgpu::BufferDescriptor desc{};
        if (!conv(desc.label, descriptor.label) ||
            !conv(desc.mappedAtCreation, descriptor.mappedAtCreation) ||
            !conv(desc.size, descriptor.size) || !conv(desc.usage, descriptor.usage)) {
            return {};
        }
        return interop::GPUBuffer::Create<GPUBuffer>(env, device_.CreateBuffer(&desc), desc,
                                                     device_, async_);
    }

    interop::Interface<interop::GPUTexture> GPUDevice::createTexture(
        Napi::Env env,
        interop::GPUTextureDescriptor descriptor) {
        Converter conv(env);

        wgpu::TextureDescriptor desc{};
        if (!conv(desc.label, descriptor.label) || !conv(desc.usage, descriptor.usage) ||  //
            !conv(desc.size, descriptor.size) ||                                           //
            !conv(desc.dimension, descriptor.dimension) ||                                 //
            !conv(desc.mipLevelCount, descriptor.mipLevelCount) ||                         //
            !conv(desc.sampleCount, descriptor.sampleCount) ||                             //
            !conv(desc.format, descriptor.format)) {
            return {};
        }
        return interop::GPUTexture::Create<GPUTexture>(env, device_.CreateTexture(&desc));
    }

    interop::Interface<interop::GPUSampler> GPUDevice::createSampler(
        Napi::Env env,
        std::optional<interop::GPUSamplerDescriptor> descriptor) {
        Converter conv(env);

        if (descriptor.has_value()) {
            wgpu::SamplerDescriptor desc{};
            if (!conv(desc.label, descriptor->label) ||                //
                !conv(desc.addressModeU, descriptor->addressModeU) ||  //
                !conv(desc.addressModeV, descriptor->addressModeV) ||  //
                !conv(desc.addressModeW, descriptor->addressModeW) ||  //
                !conv(desc.magFilter, descriptor->magFilter) ||        //
                !conv(desc.minFilter, descriptor->minFilter) ||        //
                !conv(desc.mipmapFilter, descriptor->mipmapFilter) ||  //
                !conv(desc.lodMinClamp, descriptor->lodMinClamp) ||    //
                !conv(desc.lodMaxClamp, descriptor->lodMaxClamp) ||    //
                !conv(desc.compare, descriptor->compare) ||            //
                !conv(desc.maxAnisotropy, descriptor->maxAnisotropy)) {
                return {};
            }
            return interop::GPUSampler::Create<GPUSampler>(env, device_.CreateSampler(&desc));
        }

        return interop::GPUSampler::Create<GPUSampler>(env, device_.CreateSampler());
    }

    interop::Interface<interop::GPUExternalTexture> GPUDevice::importExternalTexture(
        Napi::Env,
        interop::GPUExternalTextureDescriptor descriptor) {
        UNIMPLEMENTED();
    }

    interop::Interface<interop::GPUBindGroupLayout> GPUDevice::createBindGroupLayout(
        Napi::Env env,
        interop::GPUBindGroupLayoutDescriptor descriptor) {
        Converter conv(env);

        wgpu::BindGroupLayoutDescriptor desc{};
        if (!conv(desc.label, descriptor.label) ||
            !conv(desc.entries, desc.entryCount, descriptor.entries)) {
            return {};
        }

        return interop::GPUBindGroupLayout::Create<GPUBindGroupLayout>(
            env, device_.CreateBindGroupLayout(&desc));
    }

    interop::Interface<interop::GPUPipelineLayout> GPUDevice::createPipelineLayout(
        Napi::Env env,
        interop::GPUPipelineLayoutDescriptor descriptor) {
        Converter conv(env);

        wgpu::PipelineLayoutDescriptor desc{};
        if (!conv(desc.label, descriptor.label) ||
            !conv(desc.bindGroupLayouts, desc.bindGroupLayoutCount, descriptor.bindGroupLayouts)) {
            return {};
        }

        return interop::GPUPipelineLayout::Create<GPUPipelineLayout>(
            env, device_.CreatePipelineLayout(&desc));
    }

    interop::Interface<interop::GPUBindGroup> GPUDevice::createBindGroup(
        Napi::Env env,
        interop::GPUBindGroupDescriptor descriptor) {
        Converter conv(env);

        wgpu::BindGroupDescriptor desc{};
        if (!conv(desc.label, descriptor.label) || !conv(desc.layout, descriptor.layout) ||
            !conv(desc.entries, desc.entryCount, descriptor.entries)) {
            return {};
        }

        return interop::GPUBindGroup::Create<GPUBindGroup>(env, device_.CreateBindGroup(&desc));
    }

    interop::Interface<interop::GPUShaderModule> GPUDevice::createShaderModule(
        Napi::Env env,
        interop::GPUShaderModuleDescriptor descriptor) {
        Converter conv(env);

        wgpu::ShaderModuleWGSLDescriptor wgsl_desc{};
        wgpu::ShaderModuleDescriptor sm_desc{};
        if (!conv(wgsl_desc.source, descriptor.code) || !conv(sm_desc.label, descriptor.label)) {
            return {};
        }
        sm_desc.nextInChain = &wgsl_desc;

        return interop::GPUShaderModule::Create<GPUShaderModule>(
            env, device_.CreateShaderModule(&sm_desc), async_);
    }

    interop::Interface<interop::GPUComputePipeline> GPUDevice::createComputePipeline(
        Napi::Env env,
        interop::GPUComputePipelineDescriptor descriptor) {
        Converter conv(env);

        wgpu::ComputePipelineDescriptor desc{};
        if (!conv(desc, descriptor)) {
            return {};
        }

        return interop::GPUComputePipeline::Create<GPUComputePipeline>(
            env, device_.CreateComputePipeline(&desc));
    }

    interop::Interface<interop::GPURenderPipeline> GPUDevice::createRenderPipeline(
        Napi::Env env,
        interop::GPURenderPipelineDescriptor descriptor) {
        Converter conv(env);

        wgpu::RenderPipelineDescriptor desc{};
        if (!conv(desc, descriptor)) {
            return {};
        }

        return interop::GPURenderPipeline::Create<GPURenderPipeline>(
            env, device_.CreateRenderPipeline(&desc));
    }

    interop::Promise<interop::Interface<interop::GPUComputePipeline>>
    GPUDevice::createComputePipelineAsync(Napi::Env env,
                                          interop::GPUComputePipelineDescriptor descriptor) {
        Converter conv(env);

        wgpu::ComputePipelineDescriptor desc{};
        if (!conv(desc, descriptor)) {
            return {env};
        }

        using Promise = interop::Promise<interop::Interface<interop::GPUComputePipeline>>;

        struct Context {
            Napi::Env env;
            Promise promise;
            AsyncTask task;
        };
        auto ctx = new Context{env, env, async_};
        auto promise = ctx->promise;

        device_.CreateComputePipelineAsync(
            &desc,
            [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline,
               char const* message, void* userdata) {
                auto c = std::unique_ptr<Context>(static_cast<Context*>(userdata));

                switch (status) {
                    case WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_Success:
                        c->promise.Resolve(interop::GPUComputePipeline::Create<GPUComputePipeline>(
                            c->env, pipeline));
                        break;
                    default:
                        c->promise.Reject(Errors::OperationError(c->env));
                        break;
                }
            },
            ctx);

        return promise;
    }

    interop::Promise<interop::Interface<interop::GPURenderPipeline>>
    GPUDevice::createRenderPipelineAsync(Napi::Env env,
                                         interop::GPURenderPipelineDescriptor descriptor) {
        Converter conv(env);

        wgpu::RenderPipelineDescriptor desc{};
        if (!conv(desc, descriptor)) {
            return {env};
        }

        using Promise = interop::Promise<interop::Interface<interop::GPURenderPipeline>>;

        struct Context {
            Napi::Env env;
            Promise promise;
            AsyncTask task;
        };
        auto ctx = new Context{env, env, async_};
        auto promise = ctx->promise;

        device_.CreateRenderPipelineAsync(
            &desc,
            [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline pipeline,
               char const* message, void* userdata) {
                auto c = std::unique_ptr<Context>(static_cast<Context*>(userdata));

                switch (status) {
                    case WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_Success:
                        c->promise.Resolve(interop::GPURenderPipeline::Create<GPURenderPipeline>(
                            c->env, pipeline));
                        break;
                    default:
                        c->promise.Reject(Errors::OperationError(c->env));
                        break;
                }
            },
            ctx);

        return promise;
    }

    interop::Interface<interop::GPUCommandEncoder> GPUDevice::createCommandEncoder(
        Napi::Env env,
        std::optional<interop::GPUCommandEncoderDescriptor> descriptor) {
        wgpu::CommandEncoderDescriptor desc{};
        return interop::GPUCommandEncoder::Create<GPUCommandEncoder>(
            env, device_.CreateCommandEncoder(&desc));
    }

    interop::Interface<interop::GPURenderBundleEncoder> GPUDevice::createRenderBundleEncoder(
        Napi::Env env,
        interop::GPURenderBundleEncoderDescriptor descriptor) {
        Converter conv(env);

        wgpu::RenderBundleEncoderDescriptor desc{};
        if (!conv(desc.label, descriptor.label) ||
            !conv(desc.colorFormats, desc.colorFormatsCount, descriptor.colorFormats) ||
            !conv(desc.depthStencilFormat, descriptor.depthStencilFormat) ||
            !conv(desc.sampleCount, descriptor.sampleCount)) {
            return {};
        }

        return interop::GPURenderBundleEncoder::Create<GPURenderBundleEncoder>(
            env, device_.CreateRenderBundleEncoder(&desc));
    }

    interop::Interface<interop::GPUQuerySet> GPUDevice::createQuerySet(
        Napi::Env env,
        interop::GPUQuerySetDescriptor descriptor) {
        Converter conv(env);

        wgpu::QuerySetDescriptor desc{};
        if (!conv(desc.label, descriptor.label) || !conv(desc.type, descriptor.type) ||
            !conv(desc.count, descriptor.count) ||
            !conv(desc.pipelineStatistics, desc.pipelineStatisticsCount,
                  descriptor.pipelineStatistics)) {
            return {};
        }

        return interop::GPUQuerySet::Create<GPUQuerySet>(env, device_.CreateQuerySet(&desc));
    }

    interop::Promise<interop::Interface<interop::GPUDeviceLostInfo>> GPUDevice::getLost(
        Napi::Env env) {
        auto promise = interop::Promise<interop::Interface<interop::GPUDeviceLostInfo>>(env);
        lost_promises_.emplace_back(promise);
        return promise;
    }

    void GPUDevice::pushErrorScope(Napi::Env env, interop::GPUErrorFilter filter) {
        wgpu::ErrorFilter f = wgpu::ErrorFilter::None;
        switch (filter) {
            case interop::GPUErrorFilter::kOutOfMemory:
                f = wgpu::ErrorFilter::OutOfMemory;
                break;
            case interop::GPUErrorFilter::kValidation:
                f = wgpu::ErrorFilter::Validation;
                break;
            default:
                Napi::Error::New(env, "unhandled GPUErrorFilter value")
                    .ThrowAsJavaScriptException();
                return;
        }
        device_.PushErrorScope(f);
    }

    interop::Promise<std::optional<interop::GPUError>> GPUDevice::popErrorScope(Napi::Env env) {
        using Promise = interop::Promise<std::optional<interop::GPUError>>;
        struct Context {
            Napi::Env env;
            Promise promise;
            AsyncTask task;
        };
        auto* ctx = new Context{env, env, async_};
        auto promise = ctx->promise;

        bool ok = device_.PopErrorScope(
            [](WGPUErrorType type, char const* message, void* userdata) {
                auto c = std::unique_ptr<Context>(static_cast<Context*>(userdata));
                auto env = c->env;
                switch (type) {
                    case WGPUErrorType::WGPUErrorType_NoError:
                        c->promise.Resolve({});
                        break;
                    case WGPUErrorType::WGPUErrorType_OutOfMemory:
                        c->promise.Resolve(interop::GPUOutOfMemoryError::Create<OOMError>(env));
                        break;
                    case WGPUErrorType::WGPUErrorType_Unknown:
                    case WGPUErrorType::WGPUErrorType_DeviceLost:
                    case WGPUErrorType::WGPUErrorType_Validation:
                        c->promise.Resolve(
                            interop::GPUValidationError::Create<ValidationError>(env, message));
                        break;
                    default:
                        c->promise.Reject("unhandled error type");
                        break;
                }
            },
            ctx);

        if (ok) {
            return promise;
        }

        delete ctx;
        Promise p(env);
        p.Resolve(
            interop::GPUValidationError::Create<ValidationError>(env, "failed to pop error scope"));
        return p;
    }

    std::optional<std::string> GPUDevice::getLabel(Napi::Env) {
        UNIMPLEMENTED();
    };

    void GPUDevice::setLabel(Napi::Env, std::optional<std::string> value) {
        UNIMPLEMENTED();
    };

    interop::Interface<interop::EventHandler> GPUDevice::getOnuncapturederror(Napi::Env) {
        UNIMPLEMENTED();
    }

    void GPUDevice::setOnuncapturederror(Napi::Env,
                                         interop::Interface<interop::EventHandler> value) {
        UNIMPLEMENTED();
    }

    void GPUDevice::addEventListener(
        Napi::Env,
        std::string type,
        std::optional<interop::Interface<interop::EventListener>> callback,
        std::optional<std::variant<interop::AddEventListenerOptions, bool>> options) {
        UNIMPLEMENTED();
    }

    void GPUDevice::removeEventListener(
        Napi::Env,
        std::string type,
        std::optional<interop::Interface<interop::EventListener>> callback,
        std::optional<std::variant<interop::EventListenerOptions, bool>> options) {
        UNIMPLEMENTED();
    }

    bool GPUDevice::dispatchEvent(Napi::Env, interop::Interface<interop::Event> event) {
        UNIMPLEMENTED();
    }

}}  // namespace wgpu::binding
