// 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) {}
    // NOLINTNEXTLINE(runtime/explicit)
    ClampedInteger(T value) : value(value) {}
    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) {}
    // NOLINTNEXTLINE(runtime/explicit)
    EnforceRangeInteger(T value) : value(value) {}
    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.
    inline operator napi_value() const { return object; }
    inline operator const Napi::Value&() const { return object; }
    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.
    inline operator napi_value() const { return state_->deferred.Promise(); }
    inline operator Napi::Value() const { return state_->deferred.Promise(); }
    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.
    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_
