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

#ifndef DAWN_NODE_BINDING_CONVERTER_H_
#define DAWN_NODE_BINDING_CONVERTER_H_

#include <functional>
#include <type_traits>

#include "dawn/webgpu_cpp.h"
#include "dawn_native/DawnNative.h"
#include "napi.h"
#include "src/dawn_node/binding/Errors.h"
#include "src/dawn_node/interop/WebGPU.h"

namespace wgpu::binding {

    // ImplOfTraits is a traits helper that is used to associate the interop interface type to the
    // binding implementation type.
    template <typename T>
    struct ImplOfTraits {};

    // DECLARE_IMPL() is a macro that declares a specialization of ImplOfTraits so that
    // `typename ImplOfTraits<interop::NAME>::type` is equivalent to `binding::NAME`.
#define DECLARE_IMPL(NAME)               \
    class NAME;                          \
    template <>                          \
    struct ImplOfTraits<interop::NAME> { \
        using type = binding::NAME;      \
    }

    // Declare the interop interface to binding implementations
    DECLARE_IMPL(GPUBindGroup);
    DECLARE_IMPL(GPUBindGroupLayout);
    DECLARE_IMPL(GPUBuffer);
    DECLARE_IMPL(GPUPipelineLayout);
    DECLARE_IMPL(GPUQuerySet);
    DECLARE_IMPL(GPURenderBundle);
    DECLARE_IMPL(GPURenderPipeline);
    DECLARE_IMPL(GPUSampler);
    DECLARE_IMPL(GPUShaderModule);
    DECLARE_IMPL(GPUTexture);
    DECLARE_IMPL(GPUTextureView);
#undef DECLARE_IMPL

    // Helper for obtaining the binding implementation type from the interop interface type
    template <typename T>
    using ImplOf = typename ImplOfTraits<T>::type;

    // Converter is a utility class for converting IDL generated interop types into Dawn types.
    // As the Dawn C++ API uses raw C pointers for a number of its interfaces, Converter performs
    // heap allocations for conversions of vector or optional types. These pointers are
    // automatically freed when the Converter is destructed.
    class Converter {
      public:
        Converter(Napi::Env e) : env(e) {
        }
        ~Converter();

        // Conversion function. Converts the interop type IN to the Dawn type OUT.
        // Returns true on success, false on failure.
        template <typename OUT, typename IN>
        [[nodiscard]] inline bool operator()(OUT&& out, IN&& in) {
            return Convert(std::forward<OUT>(out), std::forward<IN>(in));
        }

        // Vector conversion function. Converts the vector of interop type IN to a pointer of
        // elements of Dawn type OUT, which is assigned to 'out_els'.
        // out_count is assigned the number of elements in 'in'.
        // Returns true on success, false on failure.
        // The pointer assigned to 'out_els' is valid until the Converter is destructed.
        template <typename OUT, typename IN>
        [[nodiscard]] inline bool operator()(OUT*& out_els,
                                             uint32_t& out_count,
                                             const std::vector<IN>& in) {
            return Convert(out_els, out_count, in);
        }

        // Returns the Env that this Converter was constructed with.
        inline Napi::Env Env() const {
            return env;
        }

        // BufferSource is the converted type of interop::BufferSource.
        struct BufferSource {
            void* data;
            size_t size;
        };

      private:
        // Below are the various overloads of Convert() used to convert the interop -> Dawn types.
        [[nodiscard]] bool Convert(wgpu::Extent3D& out, const interop::GPUExtent3D& in);

        [[nodiscard]] bool Convert(wgpu::Origin3D& out, const interop::GPUOrigin3DDict& in);

        [[nodiscard]] bool Convert(wgpu::Color& out, const interop::GPUColor& in);

        [[nodiscard]] bool Convert(wgpu::Origin3D& out,
                                   const std::vector<interop::GPUIntegerCoordinate>& in);

        [[nodiscard]] bool Convert(wgpu::TextureAspect& out, const interop::GPUTextureAspect& in);

        [[nodiscard]] bool Convert(wgpu::ImageCopyTexture& out,
                                   const interop::GPUImageCopyTexture& in);

        [[nodiscard]] bool Convert(wgpu::ImageCopyBuffer& out,
                                   const interop::GPUImageCopyBuffer& in);

        [[nodiscard]] bool Convert(BufferSource& out, interop::BufferSource in);

        [[nodiscard]] bool Convert(wgpu::TextureDataLayout& out,
                                   const interop::GPUImageDataLayout& in);

        [[nodiscard]] bool Convert(wgpu::TextureFormat& out, const interop::GPUTextureFormat& in);

        [[nodiscard]] bool Convert(wgpu::TextureUsage& out,
                                   const interop::GPUTextureUsageFlags& in);

        [[nodiscard]] bool Convert(wgpu::ColorWriteMask& out,
                                   const interop::GPUColorWriteFlags& in);

        [[nodiscard]] bool Convert(wgpu::BufferUsage& out, const interop::GPUBufferUsageFlags& in);

        [[nodiscard]] bool Convert(wgpu::MapMode& out, const interop::GPUMapModeFlags& in);

        [[nodiscard]] bool Convert(wgpu::ShaderStage& out, const interop::GPUShaderStageFlags& in);

        [[nodiscard]] bool Convert(wgpu::TextureDimension& out,
                                   const interop::GPUTextureDimension& in);

        [[nodiscard]] bool Convert(wgpu::TextureViewDimension& out,
                                   const interop::GPUTextureViewDimension& in);

        [[nodiscard]] bool Convert(wgpu::ProgrammableStageDescriptor& out,
                                   const interop::GPUProgrammableStage& in);

        [[nodiscard]] bool Convert(wgpu::ConstantEntry& out,
                                   const std::string& in_name,
                                   wgpu::interop::GPUPipelineConstantValue in_value);

        [[nodiscard]] bool Convert(wgpu::BlendComponent& out, const interop::GPUBlendComponent& in);

        [[nodiscard]] bool Convert(wgpu::BlendFactor& out, const interop::GPUBlendFactor& in);

        [[nodiscard]] bool Convert(wgpu::BlendOperation& out, const interop::GPUBlendOperation& in);

        [[nodiscard]] bool Convert(wgpu::BlendState& out, const interop::GPUBlendState& in);

        [[nodiscard]] bool Convert(wgpu::PrimitiveState& out, const interop::GPUPrimitiveState& in);

        [[nodiscard]] bool Convert(wgpu::ColorTargetState& out,
                                   const interop::GPUColorTargetState& in);

        [[nodiscard]] bool Convert(wgpu::DepthStencilState& out,
                                   const interop::GPUDepthStencilState& in);

        [[nodiscard]] bool Convert(wgpu::MultisampleState& out,
                                   const interop::GPUMultisampleState& in);

        [[nodiscard]] bool Convert(wgpu::FragmentState& out, const interop::GPUFragmentState& in);

        [[nodiscard]] bool Convert(wgpu::PrimitiveTopology& out,
                                   const interop::GPUPrimitiveTopology& in);

        [[nodiscard]] bool Convert(wgpu::FrontFace& out, const interop::GPUFrontFace& in);

        [[nodiscard]] bool Convert(wgpu::CullMode& out, const interop::GPUCullMode& in);

        [[nodiscard]] bool Convert(wgpu::CompareFunction& out,
                                   const interop::GPUCompareFunction& in);

        [[nodiscard]] bool Convert(wgpu::IndexFormat& out, const interop::GPUIndexFormat& in);

        [[nodiscard]] bool Convert(wgpu::StencilOperation& out,
                                   const interop::GPUStencilOperation& in);

        [[nodiscard]] bool Convert(wgpu::StencilFaceState& out,
                                   const interop::GPUStencilFaceState& in);

        [[nodiscard]] bool Convert(wgpu::VertexState& out, const interop::GPUVertexState& in);

        [[nodiscard]] bool Convert(wgpu::VertexBufferLayout& out,
                                   const interop::GPUVertexBufferLayout& in);

        [[nodiscard]] bool Convert(wgpu::VertexStepMode& out, const interop::GPUVertexStepMode& in);

        [[nodiscard]] bool Convert(wgpu::VertexAttribute& out,
                                   const interop::GPUVertexAttribute& in);

        [[nodiscard]] bool Convert(wgpu::VertexFormat& out, const interop::GPUVertexFormat& in);

        [[nodiscard]] bool Convert(wgpu::RenderPassColorAttachment& out,
                                   const interop::GPURenderPassColorAttachment& in);

        [[nodiscard]] bool Convert(wgpu::RenderPassDepthStencilAttachment& out,
                                   const interop::GPURenderPassDepthStencilAttachment& in);

        [[nodiscard]] bool Convert(wgpu::LoadOp& out, const interop::GPULoadOp& in);

        [[nodiscard]] bool Convert(wgpu::StoreOp& out, const interop::GPUStoreOp& in);

        [[nodiscard]] bool Convert(wgpu::BindGroupEntry& out, const interop::GPUBindGroupEntry& in);

        [[nodiscard]] bool Convert(wgpu::BindGroupLayoutEntry& out,
                                   const interop::GPUBindGroupLayoutEntry& in);

        [[nodiscard]] bool Convert(wgpu::BufferBindingLayout& out,
                                   const interop::GPUBufferBindingLayout& in);

        [[nodiscard]] bool Convert(wgpu::SamplerBindingLayout& out,
                                   const interop::GPUSamplerBindingLayout& in);

        [[nodiscard]] bool Convert(wgpu::TextureBindingLayout& out,
                                   const interop::GPUTextureBindingLayout& in);

        [[nodiscard]] bool Convert(wgpu::StorageTextureBindingLayout& out,
                                   const interop::GPUStorageTextureBindingLayout& in);

        [[nodiscard]] bool Convert(wgpu::BufferBindingType& out,
                                   const interop::GPUBufferBindingType& in);

        [[nodiscard]] bool Convert(wgpu::SamplerBindingType& out,
                                   const interop::GPUSamplerBindingType& in);

        [[nodiscard]] bool Convert(wgpu::TextureSampleType& out,
                                   const interop::GPUTextureSampleType& in);

        [[nodiscard]] bool Convert(wgpu::StorageTextureAccess& out,
                                   const interop::GPUStorageTextureAccess& in);

        [[nodiscard]] bool Convert(wgpu::QueryType& out, const interop::GPUQueryType& in);

        [[nodiscard]] bool Convert(wgpu::PipelineStatisticName& out,
                                   const interop::GPUPipelineStatisticName& in);

        [[nodiscard]] bool Convert(wgpu::AddressMode& out, const interop::GPUAddressMode& in);

        [[nodiscard]] bool Convert(wgpu::FilterMode& out, const interop::GPUFilterMode& in);

        [[nodiscard]] bool Convert(wgpu::ComputePipelineDescriptor& out,
                                   const interop::GPUComputePipelineDescriptor& in);

        [[nodiscard]] bool Convert(wgpu::RenderPipelineDescriptor& out,
                                   const interop::GPURenderPipelineDescriptor& in);

        // std::string to C string
        inline bool Convert(const char*& out, const std::string& in) {
            out = in.c_str();
            return true;
        }

        // Pass-through (no conversion)
        template <typename T>
        inline bool Convert(T& out, const T& in) {
            out = in;
            return true;
        }

        // Integral number conversion, with dynamic limit checking
        template <typename OUT,
                  typename IN,
                  typename = std::enable_if_t<std::is_integral_v<IN> && std::is_integral_v<OUT>>>
        inline bool Convert(OUT& out, const IN& in) {
            out = static_cast<OUT>(in);
            if (static_cast<IN>(out) != in) {
                Napi::Error::New(env, "Integer value (" + std::to_string(in) +
                                          ") cannot be converted to the Dawn data type without "
                                          "truncation of the value")
                    .ThrowAsJavaScriptException();
                return false;
            }
            return true;
        }

        template <typename OUT, typename... IN_TYPES>
        inline bool Convert(OUT& out, const std::variant<IN_TYPES...>& in) {
            return std::visit([&](auto&& i) { return Convert(out, i); }, in);
        }

        // If the std::optional does not have a value, then Convert() simply returns true and 'out'
        // is not assigned a new value.
        template <typename OUT, typename IN>
        inline bool Convert(OUT& out, const std::optional<IN>& in) {
            if (in.has_value()) {
                return Convert(out, in.value());
            }
            return true;
        }

        // std::optional -> T*
        // OUT* is assigned either a pointer to the converted value, or nullptr, depending on
        // whether 'in' has a value.
        template <typename OUT,
                  typename IN,
                  typename _ = std::enable_if_t<!std::is_same_v<IN, std::string>>>
        inline bool Convert(OUT*& out, const std::optional<IN>& in) {
            if (in.has_value()) {
                auto* el = Allocate<std::remove_const_t<OUT>>();
                if (!Convert(*el, in.value())) {
                    return false;
                }
                out = el;
            } else {
                out = nullptr;
            }
            return true;
        }

        // interop::Interface -> Dawn object
        template <typename OUT, typename IN>
        inline bool Convert(OUT& out, const interop::Interface<IN>& in) {
            using Impl = ImplOf<IN>;
            out = *in.template As<Impl>();
            if (!out) {
                LOG("Dawn object has been destroyed. This should not happen");
                return false;
            }
            return true;
        }

        // vector -> raw pointer + count
        template <typename OUT, typename IN>
        inline bool Convert(OUT*& out_els, uint32_t& out_count, const std::vector<IN>& in) {
            if (in.size() == 0) {
                out_els = nullptr;
                out_count = 0;
                return true;
            }
            auto* els = Allocate<std::remove_const_t<OUT>>(in.size());
            for (size_t i = 0; i < in.size(); i++) {
                if (!Convert(els[i], in[i])) {
                    return false;
                }
            }
            out_els = els;
            return Convert(out_count, in.size());
        }

        // unordered_map -> raw pointer + count
        template <typename OUT, typename IN_KEY, typename IN_VALUE>
        inline bool Convert(OUT*& out_els,
                            uint32_t& out_count,
                            const std::unordered_map<IN_KEY, IN_VALUE>& in) {
            if (in.size() == 0) {
                out_els = nullptr;
                out_count = 0;
                return true;
            }
            auto* els = Allocate<std::remove_const_t<OUT>>(in.size());
            size_t i = 0;
            for (auto& [key, value] : in) {
                if (!Convert(els[i++], key, value)) {
                    return false;
                }
            }
            out_els = els;
            return Convert(out_count, in.size());
        }

        // std::optional<T> -> raw pointer + count
        template <typename OUT, typename IN>
        inline bool Convert(OUT*& out_els, uint32_t& out_count, const std::optional<IN>& in) {
            if (!in.has_value()) {
                out_els = nullptr;
                out_count = 0;
                return true;
            }
            return Convert(out_els, out_count, in.value());
        }

        Napi::Env env;

        // Allocate() allocates and constructs an array of 'n' elements, and returns a pointer to
        // the first element. The array is freed when the Converter is destructed.
        template <typename T>
        T* Allocate(size_t n = 1) {
            auto* ptr = new T[n]{};
            free_.emplace_back([ptr] { delete[] ptr; });
            return ptr;
        }

        std::vector<std::function<void()>> free_;
    };

}  // namespace wgpu::binding

#endif  // DAWN_NODE_BINDING_CONVERTER_H_
