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

// This file provides core interop helpers used by the code generated by the
// templates.

#ifndef SRC_DAWN_NODE_INTEROP_CORE_H_
#define SRC_DAWN_NODE_INTEROP_CORE_H_

#include <algorithm>
#include <cassert>
#include <concepts>
#include <cstdint>
#include <limits>
#include <optional>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <variant>
#include <vector>

#include "src/dawn/node/interop/NodeAPI.h"
#include "src/dawn/node/utils/Debug.h"

#define ENABLE_INTEROP_LOGGING 0  // Enable for verbose interop logging

#if ENABLE_INTEROP_LOGGING
#define INTEROP_LOG(...) LOG(__VA_ARGS__)
#else
#define INTEROP_LOG(...)
#endif

// A helper macro for constructing a PromiseInfo with the current file, function and line.
// See PromiseInfo
#define PROMISE_INFO                     \
    ::wgpu::interop::PromiseInfo {       \
        __FILE__, __FUNCTION__, __LINE__ \
    }

namespace wgpu::interop {

////////////////////////////////////////////////////////////////////////////////
// Primitive JavaScript types
////////////////////////////////////////////////////////////////////////////////
using Object = Napi::Object;
using Event = Napi::Object;
using ArrayBuffer = Napi::ArrayBuffer;
using Int8Array = Napi::TypedArrayOf<int8_t>;
using Int16Array = Napi::TypedArrayOf<int16_t>;
using Int32Array = Napi::TypedArrayOf<int32_t>;
using Uint8Array = Napi::TypedArrayOf<uint8_t>;
using Uint16Array = Napi::TypedArrayOf<uint16_t>;
using Uint32Array = Napi::TypedArrayOf<uint32_t>;
using Float32Array = Napi::TypedArrayOf<float>;
using Float64Array = Napi::TypedArrayOf<double>;
using DataView = Napi::TypedArray;

// Datatype used for undefined values.
struct UndefinedType {};
inline constexpr UndefinedType Undefined;

template <typename T>
using FrozenArray = std::vector<T>;

// A wrapper class for integers that's as transparent as possible and is used to distinguish
// that the type is tagged with the [Clamp] WebIDL attribute.
template <typename T>
    requires std::integral<T>
struct ClampedInteger {
    using IntegerType = T;
    ClampedInteger() : value(0) {}
    explicit(false) ClampedInteger(T v) : value(v) {}
    // NOLINTNEXTLINE(google-explicit-constructor)
    operator T() const { return value; }
    T value;
};

// A wrapper class for integers that's as transparent as possible and is used to distinguish
// that the type is tagged with the [EnforceRange] WebIDL attribute.
template <typename T>
    requires std::integral<T>
struct EnforceRangeInteger {
    using IntegerType = T;
    EnforceRangeInteger() : value(0) {}
    explicit(false) EnforceRangeInteger(T v) : value(v) {}
    // NOLINTNEXTLINE(google-explicit-constructor)
    operator T() const { return value; }
    T value;
};

////////////////////////////////////////////////////////////////////////////////
// Result
////////////////////////////////////////////////////////////////////////////////

// Result is used to hold an success / error state by functions that perform JS <-> C++
// conversion
struct [[nodiscard]] Result {
    // Returns true if the operation succeeded, false if there was an error
    inline explicit operator bool() const { return error.empty(); }

    // If Result is an error, then a new Error is returned with the
    // stringified values append to the error message.
    // If Result is a success, then a success Result is returned.
    template <typename... VALUES>
    Result Append(VALUES&&... values) {
        if (*this) {
            return *this;
        }
        std::stringstream ss;
        ss << error << "\n";
        utils::Write(ss, std::forward<VALUES>(values)...);
        return {ss.str()};
    }

    // The error message, if the operation failed.
    std::string error;
};

// A successful result
extern Result Success;

// Returns a Result with the given error message
Result Error(std::string msg);

////////////////////////////////////////////////////////////////////////////////
// Interface<T>
////////////////////////////////////////////////////////////////////////////////

// Interface<T> is a templated wrapper around a JavaScript object, which
// implements the template-generated interface type T. Interfaces are returned
// by either calling T::Bind() or T::Create().
template <typename T>
class Interface {
  public:
    // Constructs an Interface with no JS object.
    inline Interface() {}

    // Constructs an Interface wrapping the given JS object.
    // The JS object must have been created with a call to T::Bind().
    explicit inline Interface(Napi::Object o) : object(o) {}

    // Implicit conversion operators to Napi objects.
    // NOLINTNEXTLINE(google-explicit-constructor)
    inline operator napi_value() const { return object; }
    // NOLINTNEXTLINE(google-explicit-constructor)
    inline operator const Napi::Value&() const { return object; }
    // NOLINTNEXTLINE(google-explicit-constructor)
    inline operator const Napi::Object&() const { return object; }

    // Member and dereference operators
    inline T* operator->() const { return T::Unwrap(object); }
    inline T* operator*() const { return T::Unwrap(object); }

    // As<IMPL>() returns the unwrapped object cast to the implementation type.
    // The interface implementation *must* be of the template type IMPL.
    template <typename IMPL>
    inline IMPL* As() const {
        return static_cast<IMPL*>(T::Unwrap(object));
    }

  private:
    Napi::Object object;
};

////////////////////////////////////////////////////////////////////////////////
// Promise<T>
////////////////////////////////////////////////////////////////////////////////

// Info holds details about where the promise was constructed.
// Used for printing debug messages when a promise is finalized without being resolved
// or rejected.
// Use the PROMISE_INFO macro to populate this structure.
struct PromiseInfo {
    const char* file = nullptr;
    const char* function = nullptr;
    int line = 0;
};

enum class PromiseState {
    Pending,
    Resolved,
    Rejected,
    Discarded,
};

namespace detail {
// Base class for Promise<T> specializations.
class PromiseBase {
  public:
    // Implicit conversion operators to Napi promises.
    // NOLINTNEXTLINE(google-explicit-constructor)
    inline operator napi_value() const { return state_->deferred.Promise(); }
    // NOLINTNEXTLINE(google-explicit-constructor)
    inline operator Napi::Value() const { return state_->deferred.Promise(); }
    // NOLINTNEXTLINE(google-explicit-constructor)
    inline operator Napi::Promise() const { return state_->deferred.Promise(); }

    // Comparison operator between promises
    friend bool operator==(const PromiseBase& lhs, const PromiseBase& rhs) {
        return lhs.state_ == rhs.state_;
    }
    friend bool operator!=(const PromiseBase& lhs, const PromiseBase& rhs) { return !(lhs == rhs); }

    // Reject() rejects the promise with the given failure value.
    void Reject(Napi::Value value) const {
        state_->deferred.Reject(value);
        state_->state = PromiseState::Rejected;
    }
    void Reject(Napi::Error err) const { Reject(err.Value()); }
    void Reject(std::string err) const { Reject(Napi::Error::New(state_->deferred.Env(), err)); }

    PromiseState GetState() const { return state_->state; }

    // Place the promise into the Discarded state.
    // This state will not throw a fatal error if this promise has not been rejected or resolved by
    // the time it is finalized. This is useful for Node tear-down where the attempting to create
    // new objects will result in a fatal error.
    void Discard() { state_->state = PromiseState::Discarded; }

  protected:
    void Resolve(Napi::Value value) const {
        state_->deferred.Resolve(value);
        state_->state = PromiseState::Resolved;
    }

    struct State {
        Napi::Promise::Deferred deferred;
        PromiseInfo info;
        PromiseState state = PromiseState::Pending;
    };

    PromiseBase(Napi::Env env, const PromiseInfo& info)
        : state_(new State{Napi::Promise::Deferred::New(env), info}) {
        state_->deferred.Promise().AddFinalizer(
            [](Napi::Env, State* state) {
                if (state->state == PromiseState::Pending) {
                    ::wgpu::utils::Fatal("Promise not resolved or rejected", state->info.file,
                                         state->info.line, state->info.function);
                }
                delete state;
            },
            state_);
    }

    State* const state_;
};
}  // namespace detail

// A tag used in a Promise constructor to say it won't be used and doesn't need to be initialized.
struct UnusedPromiseTag {};
inline constexpr UnusedPromiseTag kUnusedPromise;

// Promise<T> is a templated wrapper around a JavaScript promise, which can
// resolve to the template type T.
template <typename T>
class Promise : public detail::PromiseBase {
  public:
    // Constructor
    Promise(Napi::Env env, const PromiseInfo& info) : PromiseBase(env, info) {}
    Promise(Napi::Env env, UnusedPromiseTag) : PromiseBase(env, PROMISE_INFO) {
        Reject("Unused Promise, you should never see this!");
    }

    // Resolve() fulfills the promise with the given value.
    void Resolve(T&& value) const {
        PromiseBase::Resolve(ToJS(state_->deferred.Env(), std::forward<T>(value)));
    }
};

// Specialization for Promises that resolve with no value
template <>
class Promise<void> : public detail::PromiseBase {
  public:
    // Constructor
    Promise(Napi::Env env, const PromiseInfo& info) : PromiseBase(env, info) {}
    Promise(Napi::Env env, UnusedPromiseTag) : PromiseBase(env, PROMISE_INFO) {
        Reject("Unused Promise, you should never see this!");
    }

    // Resolve() fulfills the promise.
    void Resolve() const { PromiseBase::Resolve(state_->deferred.Env().Undefined()); }
};

////////////////////////////////////////////////////////////////////////////////
// Converter<T>
////////////////////////////////////////////////////////////////////////////////

// Converter<T> is specialized for each type T which can be converted from C++
// to JavaScript, or JavaScript to C++.
// Each specialization of Converter<T> is expected to have two static methods
// with the signatures:
//
//  // FromJS() converts the JavaScript value 'in' to the C++ value 'out'.
//  static Result FromJS(Napi::Env, Napi::Value in, T& out);
//
//  // ToJS() converts the C++ value 'in' to a JavaScript value, and returns
//  // this value.
//  static Napi::Value ToJS(Napi::Env, T in);
template <typename T>
class Converter {};

template <>
class Converter<Napi::Object> {
  public:
    static inline Result FromJS(Napi::Env, Napi::Value value, Napi::Object& out) {
        if (value.IsObject()) {
            out = value.ToObject();
            return Success;
        }
        return Error("value is not an object");
    }
    static inline Napi::Value ToJS(Napi::Env, Napi::Object value) { return value; }
};

template <>
class Converter<ArrayBuffer> {
  public:
    static inline Result FromJS(Napi::Env, Napi::Value value, ArrayBuffer& out) {
        if (value.IsArrayBuffer()) {
            out = value.As<ArrayBuffer>();
            return Success;
        }
        return Error("value is not a ArrayBuffer");
    }
    static inline Napi::Value ToJS(Napi::Env, ArrayBuffer value) { return value; }
};

template <>
class Converter<Napi::TypedArray> {
  public:
    static inline Result FromJS(Napi::Env, Napi::Value value, Napi::TypedArray& out) {
        if (value.IsTypedArray()) {
            out = value.As<Napi::TypedArray>();
            return Success;
        }
        return Error("value is not a TypedArray");
    }
    static inline Napi::Value ToJS(Napi::Env, ArrayBuffer value) { return value; }
};

template <typename T>
class Converter<Napi::TypedArrayOf<T>> {
  public:
    // clang-format off
        // The Napi element type of T
        static constexpr napi_typedarray_type element_type =
              std::is_same<T, int8_t>::value   ? napi_int8_array
            : std::is_same<T, uint8_t>::value  ? napi_uint8_array
            : std::is_same<T, int16_t>::value  ? napi_int16_array
            : std::is_same<T, uint16_t>::value ? napi_uint16_array
            : std::is_same<T, int32_t>::value  ? napi_int32_array
            : std::is_same<T, uint32_t>::value ? napi_uint32_array
            : std::is_same<T, float>::value    ? napi_float32_array
            : std::is_same<T, double>::value   ? napi_float64_array
            : std::is_same<T, int64_t>::value  ? napi_bigint64_array
            : std::is_same<T, uint64_t>::value ? napi_biguint64_array
            : static_cast<napi_typedarray_type>(-1);
    // clang-format on
    static_assert(static_cast<int>(element_type) >= 0,
                  "unsupported T type for Napi::TypedArrayOf<T>");
    static inline Result FromJS(Napi::Env, Napi::Value value, Napi::TypedArrayOf<T>& out) {
        if (value.IsTypedArray()) {
            auto arr = value.As<Napi::TypedArrayOf<T>>();
            if (arr.TypedArrayType() == element_type) {
                out = arr;
                return Success;
            }
            return Error("value is not a TypedArray of the correct element type");
        }
        return Error("value is not a TypedArray");
    }
    static inline Napi::Value ToJS(Napi::Env, ArrayBuffer value) { return value; }
};

template <>
class Converter<Napi::Function> {
  public:
    static inline Result FromJS(Napi::Env, Napi::Value value, Napi::Function& out) {
        if (value.IsFunction()) {
            out = value.As<Napi::Function>();
            return Success;
        }
        return Error("value is not a Function");
    }
    static inline Napi::Value ToJS(Napi::Env, Napi::Function value) { return value; }
};

template <>
class Converter<std::string> {
  public:
    static Result FromJS(Napi::Env, Napi::Value, std::string&);
    static Napi::Value ToJS(Napi::Env, std::string);
};

template <>
class Converter<bool> {
  public:
    static Result FromJS(Napi::Env, Napi::Value, bool&);
    static Napi::Value ToJS(Napi::Env, bool);
};

template <>
class Converter<int8_t> {
  public:
    static Result FromJS(Napi::Env, Napi::Value, int8_t&);
    static Napi::Value ToJS(Napi::Env, int8_t);
};

template <>
class Converter<uint8_t> {
  public:
    static Result FromJS(Napi::Env, Napi::Value, uint8_t&);
    static Napi::Value ToJS(Napi::Env, uint8_t);
};

template <>
class Converter<int16_t> {
  public:
    static Result FromJS(Napi::Env, Napi::Value, int16_t&);
    static Napi::Value ToJS(Napi::Env, int16_t);
};

template <>
class Converter<uint16_t> {
  public:
    static Result FromJS(Napi::Env, Napi::Value, uint16_t&);
    static Napi::Value ToJS(Napi::Env, uint16_t);
};

template <>
class Converter<int32_t> {
  public:
    static Result FromJS(Napi::Env, Napi::Value, int32_t&);
    static Napi::Value ToJS(Napi::Env, int32_t);
};

template <>
class Converter<uint32_t> {
  public:
    static Result FromJS(Napi::Env, Napi::Value, uint32_t&);
    static Napi::Value ToJS(Napi::Env, uint32_t);
};

template <>
class Converter<int64_t> {
  public:
    static Result FromJS(Napi::Env, Napi::Value, int64_t&);
    static Napi::Value ToJS(Napi::Env, int64_t);
};

template <>
class Converter<uint64_t> {
  public:
    static Result FromJS(Napi::Env, Napi::Value, uint64_t&);
    static Napi::Value ToJS(Napi::Env, uint64_t);
};

// Sometimes size_t is uint32_t, or uint64_t. Only define the conversion to size_t if it is a
// unique type, otherwise we have C++ compilation error for the redefinition of a template.
namespace detail {
struct InvalidType;
inline constexpr bool kSizetIsUniqueType =
    !std::is_same_v<size_t, uint32_t> && !std::is_same_v<size_t, uint64_t>;
}  // namespace detail

template <>
class Converter<std::conditional_t<detail::kSizetIsUniqueType, size_t, detail::InvalidType>> {
  public:
    static Result FromJS(Napi::Env, Napi::Value, size_t&);
    static Napi::Value ToJS(Napi::Env, size_t);
};

template <>
class Converter<float> {
  public:
    static Result FromJS(Napi::Env, Napi::Value, float&);
    static Napi::Value ToJS(Napi::Env, float);
};

template <>
class Converter<double> {
  public:
    static Result FromJS(Napi::Env, Napi::Value, double&);
    static Napi::Value ToJS(Napi::Env, double);
};

// [Clamp]ed integers must convert values outside of the integer range by clamping them.
template <typename T>
class Converter<ClampedInteger<T>> {
  public:
    static Result FromJS(Napi::Env env, Napi::Value value, ClampedInteger<T>& out) {
        double doubleValue;
        Result res = Converter<double>::FromJS(env, value, doubleValue);
        if (!res) {
            return res;
        }

        // Check for clamping first.
        constexpr T kMin = std::numeric_limits<T>::min();
        constexpr T kMax = std::numeric_limits<T>::max();
        if (doubleValue < kMin) {
            out = kMin;
            return Success;
        }
        if (doubleValue > kMax) {
            out = kMax;
            return Success;
        }

        // Yay, no clamping! We can convert the integer type as usual.
        T correctValue;
        res = Converter<T>::FromJS(env, value, correctValue);
        if (!res) {
            return res;
        }
        out = correctValue;
        return Success;
    }
    static Napi::Value ToJS(Napi::Env env, const ClampedInteger<T>& value) {
        return Converter<T>::ToJS(env, value.value);
    }
};

// [EnforceRange] integers cause a TypeError when converted from out of range values
template <typename T>
class Converter<EnforceRangeInteger<T>> {
  public:
    static Result FromJS(Napi::Env env, Napi::Value value, EnforceRangeInteger<T>& out) {
        double doubleValue;
        Result res = Converter<double>::FromJS(env, value, doubleValue);
        if (!res) {
            return res;
        }

        // Check for out of range and throw a type error.
        // Note that the number must both be representable in the integer type, but also below
        // MAX_SAFE_INTEGER after which consecutive double values might skip over some integer
        // values.
        constexpr double kMaxSafeInteger = (uint64_t(1) << 53) - uint64_t(1);
        constexpr double kMinSafeInteger = -kMaxSafeInteger;

        constexpr double kMin =
            std::max(kMinSafeInteger, static_cast<double>(std::numeric_limits<T>::min()));
        constexpr double kMax =
            std::min(kMaxSafeInteger, static_cast<double>(std::numeric_limits<T>::max()));
        if (!(kMin <= doubleValue && doubleValue <= kMax)) {
            return Error("Values are out of the range of that integer.");
        }

        // Yay, no error! We can convert the integer type as usual.
        T correctValue;
        res = Converter<T>::FromJS(env, value, correctValue);
        if (!res) {
            return res;
        }
        out = correctValue;
        return Success;
    }
    static Napi::Value ToJS(Napi::Env env, const EnforceRangeInteger<T>& value) {
        return Converter<T>::ToJS(env, value.value);
    }
};

template <>
class Converter<UndefinedType> {
  public:
    static Result FromJS(Napi::Env, Napi::Value, UndefinedType&);
    static Napi::Value ToJS(Napi::Env, UndefinedType);
};

std::ostream& operator<<(std::ostream& o, const UndefinedType&);

template <typename T>
class Converter<Interface<T>> {
  public:
    static Result FromJS(Napi::Env env, Napi::Value value, Interface<T>& out) {
        if (!value.IsObject()) {
            return Error("value is not object");
        }
        auto obj = value.As<Napi::Object>();
        if (!T::Unwrap(obj)) {
            return Error("object is not of the correct interface type");
        }
        out = Interface<T>(obj);
        return Success;
    }
    static Napi::Value ToJS(Napi::Env env, const Interface<T>& value) { return {env, value}; }
};

template <typename T>
class Converter<std::optional<T>> {
  public:
    static Result FromJS(Napi::Env env, Napi::Value value, std::optional<T>& out) {
        if (value.IsNull() || value.IsUndefined()) {
            out.reset();
            return Success;
        }
        T v{};
        auto res = Converter<T>::FromJS(env, value, v);
        if (!res) {
            return res;
        }
        out = std::move(v);
        return Success;
    }
    static Napi::Value ToJS(Napi::Env env, std::optional<T> value) {
        if (value.has_value()) {
            return Converter<T>::ToJS(env, value.value());
        }
        return env.Null();
    }
};

template <typename T>
class Converter<std::vector<T>> {
  public:
    static inline Result FromJS(Napi::Env env, Napi::Value value, std::vector<T>& out) {
        if (!value.IsArray()) {
            return Error("value is not an array");
        }
        auto arr = value.As<Napi::Array>();
        std::vector<T> vec(arr.Length());
        for (size_t i = 0; i < vec.size(); i++) {
            auto res = Converter<T>::FromJS(env, arr[static_cast<uint32_t>(i)], vec[i]);
            if (!res) {
                return res.Append("for array element ", i);
            }
        }
        out = std::move(vec);
        return Success;
    }
    static inline Napi::Value ToJS(Napi::Env env, const std::vector<T>& vec) {
        auto arr = Napi::Array::New(env, vec.size());
        for (size_t i = 0; i < vec.size(); i++) {
            arr.Set(static_cast<uint32_t>(i), Converter<T>::ToJS(env, vec[i]));
        }
        return arr;
    }
};

template <typename K, typename V>
class Converter<std::unordered_map<K, V>> {
  public:
    static inline Result FromJS(Napi::Env env, Napi::Value value, std::unordered_map<K, V>& out) {
        if (!value.IsObject()) {
            return Error("value is not an object");
        }
        auto obj = value.ToObject();
        auto keys = obj.GetPropertyNames();
        std::unordered_map<K, V> map(keys.Length());
        for (uint32_t i = 0; i < static_cast<uint32_t>(keys.Length()); i++) {
            K key{};
            V val{};
            auto key_res = Converter<K>::FromJS(env, keys[i], key);
            if (!key_res) {
                return key_res.Append("for object key");
            }
            auto value_res = Converter<V>::FromJS(env, obj.Get(keys[i]), val);
            if (!value_res) {
                return value_res.Append("for object value of key: ", key);
            }
            map[key] = val;
        }
        out = std::move(map);
        return Success;
    }
    static inline Napi::Value ToJS(Napi::Env env, std::unordered_map<K, V> value) {
        auto obj = Napi::Object::New(env);
        for (auto it : value) {
            obj.Set(Converter<K>::ToJS(env, it.first), Converter<V>::ToJS(env, it.second));
        }
        return obj;
    }
};

template <typename... TYPES>
class Converter<std::variant<TYPES...>> {
    template <typename TY>
    static inline Result TryFromJS(Napi::Env env, Napi::Value value, std::variant<TYPES...>& out) {
        TY v{};
        auto res = Converter<TY>::FromJS(env, value, v);
        if (!res) {
            return Error("no possible types matched");
        }
        out = std::move(v);
        return Success;
    }

    template <typename T0, typename T1, typename... TN>
    static inline Result TryFromJS(Napi::Env env, Napi::Value value, std::variant<TYPES...>& out) {
        if (TryFromJS<T0>(env, value, out)) {
            return Success;
        }
        return TryFromJS<T1, TN...>(env, value, out);
    }

  public:
    static inline Result FromJS(Napi::Env env, Napi::Value value, std::variant<TYPES...>& out) {
        return TryFromJS<TYPES...>(env, value, out);
    }
    static inline Napi::Value ToJS(Napi::Env env, std::variant<TYPES...> value) {
        return std::visit(
            [&](auto&& v) {
                using T = std::remove_cv_t<std::remove_reference_t<decltype(v)>>;
                return Converter<T>::ToJS(env, v);
            },
            value);
    }
};

template <typename T>
class Converter<Promise<T>> {
  public:
    static inline Result FromJS(Napi::Env env, Napi::Value, Promise<T>&) { UNIMPLEMENTED(env, {}); }
    static inline Napi::Value ToJS(Napi::Env, Promise<T> promise) { return promise; }
};

////////////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////////////

// FromJS() is a helper function which delegates to
// Converter<T>::FromJS()
template <typename T>
inline Result FromJS(Napi::Env env, Napi::Value value, T& out) {
    return Converter<T>::FromJS(env, value, out);
}

// FromJSOptional() is similar to FromJS(), but if 'value' is undefined
// then 'out' is left unassigned.
template <typename T>
inline Result FromJSOptional(Napi::Env env, Napi::Value value, T& out) {
    if (value.IsUndefined()) {
        return Success;
    }
    return Converter<T>::FromJS(env, value, out);
}

// ToJS() is a helper function which delegates to Converter<T>::ToJS()
template <typename T>
inline Napi::Value ToJS(Napi::Env env, T&& value) {
    return Converter<std::remove_cv_t<std::remove_reference_t<T>>>::ToJS(env,
                                                                         std::forward<T>(value));
}

// DefaultedParameter can be used in the tuple parameter types passed to
// FromJS(const Napi::CallbackInfo& info, PARAM_TYPES& args), for parameters
// that have a default value. If the argument is omitted in the call, then
// DefaultedParameter::default_value will be assigned to
// DefaultedParameter::value.
template <typename T>
struct DefaultedParameter {
    T value;          // The argument value assigned by FromJS()
    T default_value;  // The default value if no argument supplied

    // Implicit conversion operator. Returns value.
    // NOLINTNEXTLINE(google-explicit-constructor)
    inline operator const T&() const { return value; }
};

// IsDefaultedParameter<T>::value is true iff T is of type DefaultedParameter.
template <typename T>
struct IsDefaultedParameter {
    static constexpr bool value = false;
};
template <typename T>
struct IsDefaultedParameter<DefaultedParameter<T>> {
    static constexpr bool value = true;
};

// FromJS() is a helper function for bulk converting the arguments of 'info'.
// PARAM_TYPES is a std::tuple<> describing the C++ function parameter types.
// Parameters may be of the templated DefaultedParameter type, in which case
// the parameter will default to the default-value if omitted.
template <typename PARAM_TYPES, int BASE_INDEX = 0>
inline Result FromJS(const Napi::CallbackInfo& info, PARAM_TYPES& args) {
    if constexpr (BASE_INDEX < std::tuple_size_v<PARAM_TYPES>) {
        using T = std::tuple_element_t<BASE_INDEX, PARAM_TYPES>;
        auto& value = info[BASE_INDEX];
        auto& out = std::get<BASE_INDEX>(args);
        if constexpr (IsDefaultedParameter<T>::value) {
            // Parameter has a default value.
            // Check whether the argument was provided.
            if (value.IsNull()) {
                return Success;
            } else if (value.IsUndefined()) {
                // Use default value for this parameter
                out.value = out.default_value;
            } else {
                // Argument was provided
                auto res = FromJS(info.Env(), value, out.value);
                if (!res) {
                    return res;
                }
            }
        } else {
            // Parameter does not have a default value.
            auto res = FromJS(info.Env(), value, out);
            if (!res) {
                return res;
            }
        }
        // Convert the rest of the arguments
        return FromJS<PARAM_TYPES, BASE_INDEX + 1>(info, args);
    } else {
        return Success;
    }
}

// Calls a promise-returning function f, catching exceptions and returning them into a rejected
// promise instead. This is used to implement the WebIDL semantics for exceptions in
// promise-returning functions.
template <typename F>
Napi::Value CatchExceptionIntoPromise(Napi::Env env, F&& f) {
    Napi::Value result = f();
    assert(result.IsEmpty() || result.IsPromise());
    if (!env.IsExceptionPending()) {
        return result;
    }

    // For some reason these two calls MUST be in this order or Node crashes in Reject().
    Napi::Error error = env.GetAndClearPendingException();
    Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);

    deferred.Reject(error.Value());
    return deferred.Promise();
}

void ChainPrototype(Napi::Value baseClassValue, Napi::Function derivedClassConstructor);

}  // namespace wgpu::interop

#endif  // SRC_DAWN_NODE_INTEROP_CORE_H_
