// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// 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 COBALT_SCRIPT_V8C_CONVERSION_HELPERS_H_
#define COBALT_SCRIPT_V8C_CONVERSION_HELPERS_H_

#include <cmath>

#include <limits>
#include <string>
#include <utility>
#include <vector>

#include "base/logging.h"
#include "base/optional.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "cobalt/base/compiler.h"
#include "cobalt/base/enable_if.h"
#include "cobalt/base/token.h"
#include "cobalt/script/sequence.h"
#include "cobalt/script/v8c/algorithm_helpers.h"
#include "cobalt/script/v8c/helpers.h"
#include "cobalt/script/v8c/type_traits.h"
#include "cobalt/script/v8c/union_type_conversion_forward.h"
#include "cobalt/script/v8c/v8c_array_buffer.h"
#include "cobalt/script/v8c/v8c_array_buffer_view.h"
#include "cobalt/script/v8c/v8c_callback_interface_holder.h"
#include "cobalt/script/v8c/v8c_data_view.h"
#include "cobalt/script/v8c/v8c_global_environment.h"
#include "cobalt/script/v8c/v8c_typed_arrays.h"
#include "cobalt/script/v8c/v8c_user_object_holder.h"
#include "cobalt/script/v8c/v8c_value_handle.h"
#include "cobalt/script/value_handle.h"
#include "nb/memory_scope.h"
#include "v8/include/v8.h"

namespace cobalt {
namespace script {
namespace v8c {

// Flags that can be used as a bitmask for special conversion behaviour.
enum ConversionFlags {
  kNoConversionFlags = 0,
  kConversionFlagRestricted = 1 << 0,
  kConversionFlagNullable = 1 << 1,
  kConversionFlagTreatNullAsEmptyString = 1 << 2,
  kConversionFlagTreatUndefinedAsEmptyString = 1 << 3,
  kConversionFlagClamped = 1 << 4,
  kConversionFlagObjectOnly = 1 << 5,

  // Valid conversion flags for numeric values.
  kConversionFlagsNumeric = kConversionFlagRestricted | kConversionFlagClamped,

  // Valid conversion flags for string types.
  kConversionFlagsString = kConversionFlagTreatNullAsEmptyString |
                           kConversionFlagTreatUndefinedAsEmptyString,

  // Valid conversion flags for objects.
  kConversionFlagsObject = kConversionFlagNullable,

  // Valid conversion flags for ValueHandles.
  kConversionFlagsValueHandle =
      kConversionFlagObjectOnly | kConversionFlagNullable,

  // Valid conversion flags for callback functions.
  kConversionFlagsCallbackFunction = kConversionFlagNullable,

  // Valid conversion flags for callback interfaces.
  kConversionFlagsCallbackInterface = kConversionFlagNullable,
};

// std::string -> JSValue
inline void ToJSValue(v8::Isolate* isolate, const std::string& in_string,
                      v8::Local<v8::Value>* out_value) {
  v8::MaybeLocal<v8::String> maybe_string = v8::String::NewFromUtf8(
      isolate, in_string.data(), v8::NewStringType::kNormal, in_string.size());
  v8::Local<v8::Value> string;
  if (!maybe_string.ToLocal(&string)) {
    *out_value = v8::Null(isolate);
    return;
  }

  *out_value = string;
}

// JSValue -> std::string
void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                 int conversion_flags, ExceptionState* exception_state,
                 std::string* out_string);

// std::vector<uint8_t> -> JSValue
// Note that this conversion is specifically for the Web IDL type ByteString.
// Ideally, conversion requests would be explicit in what type they wanted to
// convert to, however it is currently solely based on input type.
inline void ToJSValue(v8::Isolate* isolate, const std::vector<uint8_t>& in_data,
                      v8::Local<v8::Value>* out_value) {
  v8::MaybeLocal<v8::String> maybe_string = v8::String::NewFromOneByte(
      isolate, in_data.data(), v8::NewStringType::kNormal, in_data.size());
  v8::Local<v8::Value> string;
  if (!maybe_string.ToLocal(&string)) {
    *out_value = v8::Null(isolate);
    return;
  }

  *out_value = string;
}

// JSValue -> std::vector<uint8_t>
void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                 int conversion_flags, ExceptionState* exception_state,
                 std::vector<uint8_t>* out_vector);

// base::Token -> JSValue
inline void ToJSValue(v8::Isolate* isolate, const base::Token& token,
                      v8::Local<v8::Value>* out_value) {
  ToJSValue(isolate, std::string(token.c_str()), out_value);
}

// bool -> JSValue
inline void ToJSValue(v8::Isolate* isolate, bool in_boolean,
                      v8::Local<v8::Value>* out_value) {
  *out_value = v8::Boolean::New(isolate, in_boolean);
}

// JSValue -> bool
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                        int conversion_flags, ExceptionState* exception_state,
                        bool* out_boolean) {
  DCHECK_EQ(conversion_flags, kNoConversionFlags)
      << "No conversion flags supported.";
  DCHECK(out_boolean);
  v8::MaybeLocal<v8::Boolean> maybe_boolean = value->ToBoolean(isolate);
  v8::Local<v8::Boolean> boolean;
  if (!maybe_boolean.ToLocal(&boolean)) {
    // When these situations happen, there must be an error in the idl
    // declaration.
    DCHECK(false);
    return;
  }
  *out_boolean = boolean->Value();
}

// signed integers <= 4 bytes -> JSValue
template <typename T>
inline void ToJSValue(
    v8::Isolate* isolate, T in_number, v8::Local<v8::Value>* out_value,
    typename base::enable_if<std::numeric_limits<T>::is_specialized &&
                                 std::numeric_limits<T>::is_integer &&
                                 std::numeric_limits<T>::is_signed &&
                                 (sizeof(T) <= 4),
                             T>::type* = NULL) {
  *out_value = v8::Integer::New(isolate, static_cast<int32_t>(in_number));
}

template <typename T>
inline const double UpperBound() {
  return std::numeric_limits<T>::max();
}

template <typename T>
inline const double LowerBound() {
  return std::numeric_limits<T>::min();
}

// The below specializations of UpperBound<T> and LowerBound<T> for 64
// bit integers use the (2^(53) - 1) and similar bounds specified in
// step 1 of ConvertToInt, see:
// https://heycam.github.io/webidl/#abstract-opdef-converttoint
template <>
inline const double UpperBound<int64_t>() {
  const double kInt64UpperBound = static_cast<double>((1ll << 53) - 1);
  return kInt64UpperBound;
}

template <>
inline const double LowerBound<int64_t>() {
  const double kInt64LowerBound = static_cast<double>(-(1ll << 53) + 1);
  return kInt64LowerBound;
}

template <>
inline const double UpperBound<uint64_t>() {
  const double kUInt64UpperBound = static_cast<double>((1ll << 53) - 1);
  return kUInt64UpperBound;
}

// TODO: Consider just having this return a value.  Or just inline in it now
// that we removed the code duplication across integer conversions.
template <typename T>
void ClampedValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                  v8::Local<v8::Value>* clamped_value) {
  v8::MaybeLocal<v8::Number> maybe_number =
      value->ToNumber(isolate->GetCurrentContext());
  v8::Local<v8::Number> number;
  if (!maybe_number.ToLocal(&number)) {
    return;
  }
  double value_of_number = number->Value();
  if (value_of_number > UpperBound<T>()) {
    value_of_number = UpperBound<T>();
  } else if (value_of_number < LowerBound<T>()) {
    value_of_number = LowerBound<T>();
  }
  *clamped_value = v8::Number::New(isolate, value_of_number);
}

namespace internal {

// A small helper metafunction for integer-like FromJSValue conversions to
// pick the right type to feed to V8, which can only be the output types
// observed here.
template <typename T>
struct IntegralTypeToOutType {
  static_assert(std::numeric_limits<T>::is_specialized &&
                    std::numeric_limits<T>::is_integer,
                "");
  using type = typename std::conditional<
      std::numeric_limits<T>::is_signed,
      typename std::conditional<(sizeof(T) <= 4), int32_t, int64_t>::type,
      typename std::conditional<(sizeof(T) <= 4), uint32_t,
                                uint64_t>::type>::type;
};

inline bool ToOutType(v8::Isolate* isolate, v8::Local<v8::Value> value,
                      int32_t* out) {
  v8::Maybe<int32_t> maybe_result =
      value->Int32Value(isolate->GetCurrentContext());
  if (!maybe_result.To(out)) {
    return false;
  }
  return true;
}

inline bool ToOutType(v8::Isolate* isolate, v8::Local<v8::Value> value,
                      int64_t* out) {
  v8::Maybe<int64_t> maybe_result =
      value->IntegerValue(isolate->GetCurrentContext());
  if (!maybe_result.To(out)) {
    return false;
  }
  *out = maybe_result.FromJust();
  return true;
}

inline bool ToOutType(v8::Isolate* isolate, v8::Local<v8::Value> value,
                      uint32_t* out) {
  v8::Maybe<uint32_t> maybe_result =
      value->Uint32Value(isolate->GetCurrentContext());
  if (!maybe_result.To(out)) {
    return false;
  }
  *out = maybe_result.FromJust();
  return true;
}

inline bool ToOutType(v8::Isolate* isolate, v8::Local<v8::Value> value,
                      uint64_t* out) {
  // V8 doesn't have anything for uint64_t (TODO: why?  More spec compliant?
  // less spec compliant?...), so this one is different.
  v8::Maybe<double> maybe_result =
      value->NumberValue(isolate->GetCurrentContext());
  if (maybe_result.IsNothing()) {
    return false;
  }
  *out = static_cast<uint64_t>(maybe_result.FromJust());
  return true;
}

}  // namespace internal

// JSValue -> integer-like
template <typename T>
inline void FromJSValue(
    v8::Isolate* isolate, v8::Local<v8::Value> value, int conversion_flags,
    ExceptionState* exception_state, T* out_number,
    typename base::enable_if<std::numeric_limits<T>::is_specialized &&
                                 std::numeric_limits<T>::is_integer,
                             T>::type* = NULL) {
  DCHECK(out_number);

  if (UNLIKELY(value->IsSymbol())) {
    exception_state->SetSimpleException(
        kTypeError, "Cannot convert a Symbol value to a number");
    return;
  }

  // Convert a JavaScript value to an integer type as specified by the
  // ECMAScript standard.
  using OutType = typename internal::IntegralTypeToOutType<T>::type;
  OutType out;
  bool success;
  if (UNLIKELY(conversion_flags & kConversionFlagClamped)) {
    v8::Local<v8::Value> clamped_value;
    ClampedValue<T>(isolate, value, &clamped_value);
    DCHECK(!clamped_value.IsEmpty());
    success = internal::ToOutType(isolate, clamped_value, &out);
  } else {
    success = internal::ToOutType(isolate, value, &out);
  }

  // It is possible for |JS::To{Uint,Int}{32,64}| to fail in certain edge
  // cases, such as application JavaScript setting up infinite recursion that
  // gets triggered by the conversion.
  if (!success) {
    // TODO: Still need to handle infinite recursion edge case here.
    // V8 does not provide APIs to determine if it is throwing exception and
    // neither does v8 provide API to alert that we might enter infinite
    // exception handling.
    exception_state->SetSimpleException(
        std::numeric_limits<T>::is_signed ? kNotInt64Type : kNotUint64Type);
    return;
  }
  *out_number = static_cast<T>(out);
}

// signed integers > 4 bytes -> JSValue
template <typename T>
inline void ToJSValue(
    v8::Isolate* isolate, T in_number, v8::Local<v8::Value>* out_value,
    typename base::enable_if<std::numeric_limits<T>::is_specialized &&
                                 std::numeric_limits<T>::is_integer &&
                                 std::numeric_limits<T>::is_signed &&
                                 (sizeof(T) > 4),
                             T>::type* = NULL) {
  *out_value = v8::Number::New(isolate, in_number);
}

// unsigned integers <= 4 bytes -> JSValue
template <typename T>
inline void ToJSValue(
    v8::Isolate* isolate, T in_number, v8::Local<v8::Value>* out_value,
    typename base::enable_if<std::numeric_limits<T>::is_specialized &&
                                 std::numeric_limits<T>::is_integer &&
                                 !std::numeric_limits<T>::is_signed &&
                                 (sizeof(T) <= 4),
                             T>::type* = NULL) {
  *out_value = v8::Integer::NewFromUnsigned(isolate, in_number);
}

// TODO: Don't specialize template on these..., have them share an impl w/
// double unsigned integers > 4 bytes -> JSValue
template <typename T>
inline void ToJSValue(
    v8::Isolate* isolate, T in_number, v8::Local<v8::Value>* out_value,
    typename base::enable_if<std::numeric_limits<T>::is_specialized &&
                                 std::numeric_limits<T>::is_integer &&
                                 !std::numeric_limits<T>::is_signed &&
                                 (sizeof(T) > 4),
                             T>::type* = NULL) {
  *out_value = v8::Number::New(isolate, in_number);
}

// double -> JSValue
template <typename T>
inline void ToJSValue(
    v8::Isolate* isolate, T in_number, v8::Local<v8::Value>* out_value,
    typename base::enable_if<std::numeric_limits<T>::is_specialized &&
                                 !std::numeric_limits<T>::is_integer,
                             T>::type* = NULL) {
  *out_value = v8::Number::New(isolate, in_number);
}

// JSValue -> double
template <typename T>
inline void FromJSValue(
    v8::Isolate* isolate, v8::Local<v8::Value> value, int conversion_flags,
    ExceptionState* exception_state, T* out_number,
    typename base::enable_if<std::numeric_limits<T>::is_specialized &&
                                 !std::numeric_limits<T>::is_integer,
                             T>::type* = NULL) {
  DCHECK_EQ(conversion_flags & ~kConversionFlagsNumeric, 0)
      << "Unexpected conversion flags found.";

  v8::MaybeLocal<v8::Number> maybe_value_as_number =
      value->ToNumber(isolate->GetCurrentContext());
  v8::Local<v8::Number> value_as_number;
  if (!maybe_value_as_number.ToLocal(&value_as_number)) {
    NOTIMPLEMENTED();
    return;
  }
  double value_as_double = value_as_number->Value();
  if ((conversion_flags & kConversionFlagRestricted) &&
      !std::isfinite(value_as_double)) {
    exception_state->SetSimpleException(kNotFinite);
    return;
  }
  *out_number = value_as_double;
}

// optional<T> -> JSValue
template <typename T>
inline void ToJSValue(v8::Isolate* isolate,
                      const base::Optional<T>& in_optional,
                      v8::Local<v8::Value>* out_value) {
  if (in_optional) {
    ToJSValue(isolate, in_optional.value(), out_value);
  } else {
    *out_value = v8::Null(isolate);
  }
}

// JSValue -> optional<T>
template <typename T>
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                        int conversion_flags, ExceptionState* exception_state,
                        base::Optional<T>* out_optional) {
  if (value->IsNullOrUndefined()) {
    *out_optional = base::nullopt;
  } else {
    *out_optional = T();
    FromJSValue(isolate, value, conversion_flags & ~kConversionFlagNullable,
                exception_state, &(out_optional->value()));
  }
}

// JSValue -> optional<std::string>
template <>
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                        int conversion_flags, ExceptionState* exception_state,
                        base::Optional<std::string>* out_optional) {
  if (value->IsNull()) {
    *out_optional = base::nullopt;
  } else if (value->IsUndefined() &&
             !(conversion_flags & kConversionFlagTreatUndefinedAsEmptyString)) {
    // If TreatUndefinedAs=EmptyString is set, skip the default conversion
    // of undefined to null.
    *out_optional = base::nullopt;
  } else {
    *out_optional = std::string();
    FromJSValue(isolate, value, conversion_flags & ~kConversionFlagNullable,
                exception_state, &(out_optional->value()));
  }
}

// ValueHandle -> JSValue
void ToJSValue(v8::Isolate* isolate,
               const ValueHandleHolder* value_handle_holder,
               v8::Local<v8::Value>* out_value);

// base::Time -> JSValue
void ToJSValue(v8::Isolate* isolate, const base::Time& time,
               v8::Local<v8::Value>* out_value);

// JSValue -> base::Time
void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                 int conversion_flags, ExceptionState* exception_state,
                 base::Time* out_time);

// JSValue -> ValueHandle
void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                 int conversion_flags, ExceptionState* exception_state,
                 V8cValueHandleHolder* out_holder);

// object -> JSValue
template <typename T>
inline void ToJSValue(v8::Isolate* isolate, const scoped_refptr<T>& in_object,
                      v8::Local<v8::Value>* out_value) {
  if (!in_object) {
    *out_value = v8::Null(isolate);
    return;
  }

  V8cGlobalEnvironment* global_environment =
      V8cGlobalEnvironment::GetFromIsolate(isolate);
  *out_value = global_environment->wrapper_factory()->GetWrapper(in_object);
}

// raw object pointer -> JSValue
template <typename T>
inline void ToJSValue(v8::Isolate* isolate, T* in_object,
                      v8::Local<v8::Value>* out_value) {
  ToJSValue(isolate, scoped_refptr<T>(in_object), out_value);
}

// JSValue -> object
template <typename T>
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                        int conversion_flags, ExceptionState* exception_state,
                        scoped_refptr<T>* out_object) {
  DCHECK_EQ(conversion_flags & ~kConversionFlagsObject, 0)
      << "Unexpected conversion flags found.";

  if (value->IsNullOrUndefined()) {
    if (!(conversion_flags & kConversionFlagNullable)) {
      exception_state->SetSimpleException(kNotNullableType);
    }
    return;
  }
  if (!value->IsObject()) {
    exception_state->SetSimpleException(kNotObjectType);
    return;
  }

  V8cGlobalEnvironment* global_environment =
      V8cGlobalEnvironment::GetFromIsolate(isolate);
  WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
  v8::Local<v8::Object> object = value.As<v8::Object>();

  // Note that |DoesObjectImplementInterface| handles the case in which
  // |object| has no |WrapperPrivate|.
  if (!wrapper_factory->DoesObjectImplementInterface(object,
                                                     base::GetTypeId<T>())) {
    exception_state->SetSimpleException(kDoesNotImplementInterface);
    return;
  }

  WrapperPrivate* wrapper_private =
      WrapperPrivate::GetFromWrapperObject(object);
  DCHECK(wrapper_private);
  *out_object = wrapper_private->wrappable<T>();
}

// CallbackInterface -> JSValue
template <typename T>
inline void ToJSValue(v8::Isolate* isolate,
                      const ScriptValue<T>* callback_interface,
                      v8::Local<v8::Value>* out_value) {
  if (!callback_interface) {
    *out_value = v8::Null(isolate);
    return;
  }

  typedef typename CallbackInterfaceTraits<T>::V8cCallbackInterfaceClass
      V8cCallbackInterfaceClass;
  // Downcast to V8cUserObjectHolder<T> so we can get the underlying JSObject.
  typedef V8cUserObjectHolder<V8cCallbackInterfaceClass>
      V8cUserObjectHolderClass;
  const V8cUserObjectHolderClass* user_object_holder =
      base::polymorphic_downcast<const V8cUserObjectHolderClass*>(
          callback_interface);

  // Shouldn't be NULL. If the callback was NULL then NULL should have been
  // passed as an argument into this function.
  // Downcast to the corresponding V8cCallbackInterface type, from which we
  // can get the implementing object.
  const V8cCallbackInterfaceClass* v8c_callback_interface =
      base::polymorphic_downcast<const V8cCallbackInterfaceClass*>(
          user_object_holder->GetValue());
  DCHECK(v8c_callback_interface);
  *out_value = v8c_callback_interface->NewLocal(isolate);
}

// JSValue -> CallbackInterface
template <typename T>
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                        int conversion_flags, ExceptionState* out_exception,
                        V8cCallbackInterfaceHolder<T>* out_callback_interface) {
  typedef T V8cCallbackInterfaceClass;
  DCHECK_EQ(conversion_flags & ~kConversionFlagsCallbackFunction, 0)
      << "No conversion flags supported.";
  if (value->IsNull()) {
    if (!(conversion_flags & kConversionFlagNullable)) {
      out_exception->SetSimpleException(kNotNullableType);
    }
    // If it is a nullable type, just return.
    return;
  }

  // https://www.w3.org/TR/WebIDL/#es-user-objects
  // Any user object can be considered to implement a user interface. Actually
  // checking if the correct properties exist will happen when the operation
  // on the callback interface is run.
  if (!value->IsObject()) {
    out_exception->SetSimpleException(kNotObjectType);
    return;
  }

  *out_callback_interface = V8cCallbackInterfaceHolder<T>(isolate, value);
}

// Sequence -> JSValue
template <typename T>
void ToJSValue(v8::Isolate* isolate, const script::Sequence<T>& sequence,
               v8::Local<v8::Value>* out_value) {
  // https://webidl.spec.whatwg.org/#es-sequence
  // 1. Let n be the length of S.
  using size_type = typename script::Sequence<T>::size_type;
  size_type count = sequence.size();

  // 2. Let A be a new Array object created as if by the expression [].
  v8::Local<v8::Array> array = v8::Array::New(isolate);

  // 3. Initialize i to be 0.
  // 4. While i < n:
  for (size_type index = 0; index < count; ++index) {
    // 4.1. Let V be the value in S at index i.
    // 4.2. Let E be the result of converting V to an ECMAScript value.
    v8::Local<v8::Value> element;
    ToJSValue(isolate, sequence.at(index), &element);

    // 4.3. Let P be the result of calling ToString(i).
    // 4.4. Call CreateDataProperty(A, P, E).
    v8::Maybe<bool> set_result =
        array->Set(isolate->GetCurrentContext(), index, element);

    // 4.5. Set i to i + 1.
  }

  // 5. Return A.
  *out_value = array;
}

// JSValue -> Sequence
template <typename T>
void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                 int conversion_flags, ExceptionState* exception_state,
                 script::Sequence<T>* out_sequence) {
  DCHECK_EQ(0, conversion_flags);
  DCHECK(out_sequence);

  // JS -> IDL type conversion procedure described here:
  // https://heycam.github.io/webidl/#es-sequence

  // 1. If Type(V) is not Object, throw a TypeError.
  if (!value->IsObject()) {
    exception_state->SetSimpleException(kNotObjectType);
    return;
  }

  // 2. Let method be ? GetMethod(V, @@iterator).
  // 3. If method is undefined, throw a TypeError.
  v8::Local<v8::Object> iterable = value.As<v8::Object>();

  v8::Local<v8::Object> iterator;
  V8cExceptionState* v8c_exception_state =
      base::polymorphic_downcast<V8cExceptionState*>(exception_state);
  if (!GetIterator(isolate, iterable, v8c_exception_state).ToLocal(&iterator)) {
    DCHECK(v8c_exception_state->is_exception_set());
    return;
  }

  v8::Local<v8::String> next_key = NewInternalString(isolate, "next");
  v8::Local<v8::String> value_key = NewInternalString(isolate, "value");
  v8::Local<v8::String> done_key = NewInternalString(isolate, "done");
  v8::Local<v8::Context> context = isolate->GetCurrentContext();

  // 4. Return the result of creating a sequence from V and method.
  // https://heycam.github.io/webidl/#create-sequence-from-iterable
  for (;;) {
    // Let next be ? IteratorStep(iter).
    v8::Local<v8::Value> next;
    if (!iterator->Get(context, next_key).ToLocal(&next)) {
      exception_state->SetSimpleException(kTypeError, "");
      return;
    }
    if (!next->IsFunction()) {
      exception_state->SetSimpleException(kTypeError,
                                          "Iterator.next should be callable.");
      return;
    }

    v8::Local<v8::Value> next_result;
    if (!next.As<v8::Function>()
             ->Call(context, iterator, 0, nullptr)
             .ToLocal(&next_result)) {
      return;
    }
    if (!next_result->IsObject()) {
      exception_state->SetSimpleException(
          kTypeError, "Iterator.next did not return an object.");
      return;
    }

    // Let nextItem be ? IteratorValue(next).
    v8::Local<v8::Object> result_object = next_result.As<v8::Object>();
    v8::Local<v8::Value> next_item;
    v8::Local<v8::Value> done;
    if (!result_object->Get(context, value_key).ToLocal(&next_item) ||
        !result_object->Get(context, done_key).ToLocal(&done)) {
      return;
    }

    if (done->BooleanValue(isolate)) {
      break;
    }

    // Initialize S_i to the result of converting nextItem to an IDL value
    // of type T.
    T idl_next_item;
    FromJSValue(isolate, next_item, conversion_flags, exception_state,
                &idl_next_item);
    if (v8c_exception_state->is_exception_set()) {
      return;
    }
    out_sequence->push_back(idl_next_item);
  }
}

// Promise -> JSValue
template <typename T>
void ToJSValue(v8::Isolate* isolate,
               const ScriptValue<Promise<T>>* promise_holder,
               v8::Local<v8::Value>* out_value);

// Promise -> JSValue
template <typename T>
void ToJSValue(v8::Isolate* isolate, ScriptValue<Promise<T>>* promise_holder,
               v8::Local<v8::Value>* out_value);

// JSValue -> Promise
template <typename T>
void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                 int conversion_flags, ExceptionState* exception_state,
                 script::Promise<T>* out_promise) {
  // TODO(b/228976500): Implement conversion from JS to native for Promise<T>.
  // https://webidl.spec.whatwg.org/#es-promise
  NOTIMPLEMENTED();
}

// script::Handle<T> -> JSValue
template <typename T>
void ToJSValue(v8::Isolate* isolate, const Handle<T>& local,
               v8::Local<v8::Value>* out_value) {
  TRACK_MEMORY_SCOPE("Javascript");
  ToJSValue(isolate, local.GetScriptValue(), out_value);
}

// script::Handle<JSValue> -> object
template <typename T>
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                        int conversion_flags, ExceptionState* exception_state,
                        Handle<T>* out_object) {
  DCHECK_EQ(conversion_flags & ~kConversionFlagsObject, 0)
      << "Unexpected conversion flags found.";

  if (value->IsNullOrUndefined()) {
    if (!(conversion_flags & kConversionFlagNullable)) {
      exception_state->SetSimpleException(kNotNullableType);
    }
    return;
  }

  typename TypeTraits<T>::ConversionType temporary_holder;
  FromJSValue(isolate, value, conversion_flags, exception_state,
              &temporary_holder);
  *out_object = std::move(Handle<T>(temporary_holder));
}

}  // namespace v8c
}  // namespace script
}  // namespace cobalt

// Union type conversion is generated by a pump script.
#include "cobalt/script/v8c/union_type_conversion_impl.h"

#endif  // COBALT_SCRIPT_V8C_CONVERSION_HELPERS_H_
