// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_TO_V8_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_TO_V8_H_

// ToV8() provides C++ -> V8 conversion. Note that ToV8() can return an empty
// handle. Call sites must check IsEmpty() before using return value.

#include <utility>

#include "base/containers/span.h"
#include "base/optional.h"
#include "third_party/blink/renderer/platform/bindings/callback_function_base.h"
#include "third_party/blink/renderer/platform/bindings/callback_interface_base.h"
#include "third_party/blink/renderer/platform/bindings/dom_data_store.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "v8/include/v8.h"

namespace blink {

// ScriptWrappable

inline v8::Local<v8::Value> ToV8(ScriptWrappable* impl,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  if (UNLIKELY(!impl))
    return v8::Null(isolate);
  v8::Local<v8::Value> wrapper = DOMDataStore::GetWrapper(impl, isolate);
  if (!wrapper.IsEmpty())
    return wrapper;

  wrapper = impl->Wrap(isolate, creation_context);
  DCHECK(!wrapper.IsEmpty());
  return wrapper;
}

// Callback function

inline v8::Local<v8::Value> ToV8(CallbackFunctionBase* callback,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  // |creation_context| is intentionally ignored. Callback functions are not
  // wrappers nor clonable. ToV8 on a callback function must be used only when
  // it's the same origin-domain in the same world.
  DCHECK(!callback || (callback->CallbackRelevantScriptState()->GetContext() ==
                       creation_context->CreationContext()));
  return callback ? callback->CallbackFunction().As<v8::Value>()
                  : v8::Null(isolate).As<v8::Value>();
}

// Callback interface

inline v8::Local<v8::Value> ToV8(CallbackInterfaceBase* callback,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  // |creation_context| is intentionally ignored. Callback interface objects
  // are not wrappers nor clonable. ToV8 on a callback interface object must
  // be used only when it's the same origin-domain in the same world.
  DCHECK(!callback || (callback->CallbackRelevantScriptState()->GetContext() ==
                       creation_context->CreationContext()));
  return callback ? callback->CallbackObject().As<v8::Value>()
                  : v8::Null(isolate).As<v8::Value>();
}

// Primitives

inline v8::Local<v8::Value> ToV8(const String& value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  return V8String(isolate, value);
}

inline v8::Local<v8::Value> ToV8(const char* value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  return V8String(isolate, value);
}

template <size_t sizeOfValue>
inline v8::Local<v8::Value> ToV8SignedIntegerInternal(int64_t value,
                                                      v8::Isolate*);

template <>
inline v8::Local<v8::Value> ToV8SignedIntegerInternal<4>(int64_t value,
                                                         v8::Isolate* isolate) {
  return v8::Integer::New(isolate, static_cast<int32_t>(value));
}

template <>
inline v8::Local<v8::Value> ToV8SignedIntegerInternal<8>(int64_t value,
                                                         v8::Isolate* isolate) {
  int32_t value_in32_bit = static_cast<int32_t>(value);
  if (value_in32_bit == value)
    return v8::Integer::New(isolate, value_in32_bit);
  // V8 doesn't have a 64-bit integer implementation.
  return v8::Number::New(isolate, value);
}

template <size_t sizeOfValue>
inline v8::Local<v8::Value> ToV8UnsignedIntegerInternal(uint64_t value,
                                                        v8::Isolate*);

template <>
inline v8::Local<v8::Value> ToV8UnsignedIntegerInternal<4>(
    uint64_t value,
    v8::Isolate* isolate) {
  return v8::Integer::NewFromUnsigned(isolate, static_cast<uint32_t>(value));
}

template <>
inline v8::Local<v8::Value> ToV8UnsignedIntegerInternal<8>(
    uint64_t value,
    v8::Isolate* isolate) {
  uint32_t value_in32_bit = static_cast<uint32_t>(value);
  if (value_in32_bit == value)
    return v8::Integer::NewFromUnsigned(isolate, value_in32_bit);
  // V8 doesn't have a 64-bit integer implementation.
  return v8::Number::New(isolate, value);
}

inline v8::Local<v8::Value> ToV8(int value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  return ToV8SignedIntegerInternal<sizeof value>(value, isolate);
}

inline v8::Local<v8::Value> ToV8(long value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  return ToV8SignedIntegerInternal<sizeof value>(value, isolate);
}

inline v8::Local<v8::Value> ToV8(long long value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  return ToV8SignedIntegerInternal<sizeof value>(value, isolate);
}

inline v8::Local<v8::Value> ToV8(unsigned value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  return ToV8UnsignedIntegerInternal<sizeof value>(value, isolate);
}

inline v8::Local<v8::Value> ToV8(unsigned long value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  return ToV8UnsignedIntegerInternal<sizeof value>(value, isolate);
}

inline v8::Local<v8::Value> ToV8(unsigned long long value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  return ToV8UnsignedIntegerInternal<sizeof value>(value, isolate);
}

inline v8::Local<v8::Value> ToV8(double value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  return v8::Number::New(isolate, value);
}

inline v8::Local<v8::Value> ToV8(bool value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  return v8::Boolean::New(isolate, value);
}

// Identity operator

inline v8::Local<v8::Value> ToV8(v8::Local<v8::Value> value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate*) {
  return value;
}

// Undefined

struct ToV8UndefinedGenerator {
  DISALLOW_NEW();
};  // Used only for having toV8 return v8::Undefined.

inline v8::Local<v8::Value> ToV8(const ToV8UndefinedGenerator& value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  return v8::Undefined(isolate);
}

// Forward declaration to allow interleaving with sequences.
template <typename InnerType>
inline v8::Local<v8::Value> ToV8(const base::Optional<InnerType>& value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate*);

// Array

// Declare the function here but define it later so it can call the ToV8()
// overloads below.
template <typename Sequence>
inline v8::Local<v8::Value> ToV8SequenceInternal(
    const Sequence&,
    v8::Local<v8::Object> creation_context,
    v8::Isolate*);

template <typename T, size_t Extent>
inline v8::Local<v8::Value> ToV8(base::span<T, Extent> value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  return ToV8SequenceInternal(value, creation_context, isolate);
}

template <typename T, wtf_size_t inlineCapacity>
inline v8::Local<v8::Value> ToV8(const Vector<T, inlineCapacity>& value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  return ToV8SequenceInternal(value, creation_context, isolate);
}

template <typename T, wtf_size_t inlineCapacity>
inline v8::Local<v8::Value> ToV8(const HeapVector<T, inlineCapacity>& value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  return ToV8SequenceInternal(value, creation_context, isolate);
}

// The following two overloads are also used to convert record<K,V> IDL types
// back into ECMAScript Objects.
template <typename T>
inline v8::Local<v8::Value> ToV8(const Vector<std::pair<String, T>>& value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  v8::Local<v8::Object> object;
  {
    v8::Context::Scope context_scope(creation_context->CreationContext());
    object = v8::Object::New(isolate);
  }
  v8::Local<v8::Context> context = isolate->GetCurrentContext();
  for (unsigned i = 0; i < value.size(); ++i) {
    v8::Local<v8::Value> v8_value = ToV8(value[i].second, object, isolate);
    if (v8_value.IsEmpty())
      v8_value = v8::Undefined(isolate);
    bool created_property;
    if (!object
             ->CreateDataProperty(
                 context, V8AtomicString(isolate, value[i].first), v8_value)
             .To(&created_property) ||
        !created_property) {
      return v8::Local<v8::Value>();
    }
  }
  return object;
}

template <typename T>
inline v8::Local<v8::Value> ToV8(const HeapVector<std::pair<String, T>>& value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  v8::Local<v8::Object> object;
  {
    v8::Context::Scope context_scope(creation_context->CreationContext());
    object = v8::Object::New(isolate);
  }
  v8::Local<v8::Context> context = isolate->GetCurrentContext();
  for (unsigned i = 0; i < value.size(); ++i) {
    v8::Local<v8::Value> v8_value = ToV8(value[i].second, object, isolate);
    if (v8_value.IsEmpty())
      v8_value = v8::Undefined(isolate);
    bool created_property;
    if (!object
             ->CreateDataProperty(
                 context, V8AtomicString(isolate, value[i].first), v8_value)
             .To(&created_property) ||
        !created_property) {
      return v8::Local<v8::Value>();
    }
  }
  return object;
}

template <typename Sequence>
inline v8::Local<v8::Value> ToV8SequenceInternal(
    const Sequence& sequence,
    v8::Local<v8::Object> creation_context,
    v8::Isolate* isolate) {
  RUNTIME_CALL_TIMER_SCOPE(isolate,
                           RuntimeCallStats::CounterId::kToV8SequenceInternal);
  v8::Local<v8::Array> array;
  {
    v8::Context::Scope context_scope(creation_context->CreationContext());
    array = v8::Array::New(isolate, SafeCast<int>(sequence.size()));
  }
  v8::Local<v8::Context> context = isolate->GetCurrentContext();
  uint32_t index = 0;
  typename Sequence::const_iterator end = sequence.end();
  for (typename Sequence::const_iterator iter = sequence.begin(); iter != end;
       ++iter) {
    v8::Local<v8::Value> value = ToV8(*iter, array, isolate);
    if (value.IsEmpty())
      value = v8::Undefined(isolate);
    bool created_property;
    if (!array->CreateDataProperty(context, index++, value)
             .To(&created_property) ||
        !created_property) {
      return v8::Local<v8::Value>();
    }
  }
  return array;
}

// Nullable

template <typename InnerType>
inline v8::Local<v8::Value> ToV8(const base::Optional<InnerType>& value,
                                 v8::Local<v8::Object> creation_context,
                                 v8::Isolate* isolate) {
  if (!value)
    return v8::Null(isolate);
  return ToV8(*value, creation_context, isolate);
}

// In all cases allow script state instead of creation context + isolate.
// Use this function only if the call site does not otherwise need the global,
// since v8::Context::Global is heavy.
template <typename T>
inline v8::Local<v8::Value> ToV8(T&& value, ScriptState* script_state) {
  return ToV8(std::forward<T>(value), script_state->GetContext()->Global(),
              script_state->GetIsolate());
}

// Only declare ToV8(void*,...) for checking function overload mismatch.
// This ToV8(void*,...) should be never used. So we will find mismatch
// because of "unresolved external symbol".
// Without ToV8(void*, ...), call to toV8 with T* will match with
// ToV8(bool, ...) if T is not a subclass of ScriptWrappable or if T is
// declared but not defined (so it's not clear that T is a subclass of
// ScriptWrappable).
// This hack helps detect such unwanted implicit conversions from T* to bool.
v8::Local<v8::Value> ToV8(void* value,
                          v8::Local<v8::Object> creation_context,
                          v8::Isolate*) = delete;

}  // namespace blink

#endif  // ToV8ForPlatform_h
