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

// 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 <cstdint>
#include <limits>
// TODO(https://crbug.com/dawn/1379) Update cpplint and remove NOLINT
#include <optional>  // NOLINT(build/include_order)
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
// TODO(https://crbug.com/dawn/1379) Update cpplint and remove NOLINT
#include <variant>  // NOLINT(build/include_order)
#include <vector>

#include "src/dawn/node/interop/Napi.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 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 {};
static 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>
struct ClampedInteger {
    static_assert(std::is_integral_v<T>);

    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>
struct EnforceRangeInteger {
    static_assert(std::is_integral_v<T>);

    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 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,
};

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(); }

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

  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

// 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) {}

    // 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) {}

    // 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<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);
};

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.
        constexpr double kMin = static_cast<double>(std::numeric_limits<T>::min());
        constexpr double kMax = 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);
};

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 value{};
            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]), value);
            if (!value_res) {
                return value_res.Append("for object value of key: ", key);
            }
            map[key] = value;
        }
        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, Napi::Value, Promise<T>&) { UNIMPLEMENTED(); }
    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 either null
// or undefined then 'out' is left unassigned.
template <typename T>
inline Result FromJSOptional(Napi::Env env, Napi::Value value, T& out) {
    if (value.IsNull() || 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() || 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;
    }
}

}  // namespace wgpu::interop

#endif  // SRC_DAWN_NODE_INTEROP_CORE_H_
