{#
 # Copyright 2016 Google Inc. 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.
 #}

{% from 'macros.cc.template' import add_extra_arguments %}
{% from 'macros.cc.template' import call_cobalt_function %}
{% from 'macros.cc.template' import check_if_object_implements_interface with context %}
{% from 'macros.cc.template' import constructor_implementation with context %}
{% from 'macros.cc.template' import function_implementation with context %}
{% from 'macros.cc.template' import get_impl_class_instance %}
{% from 'macros.cc.template' import nonstatic_function_prologue %}
{% from 'macros.cc.template' import overload_resolution_implementation with context %}
{% from 'macros.cc.template' import set_attribute_implementation with context %}
{% from 'macros.cc.template' import static_function_prologue %}

{% extends "interface-base.cc.template" %}

{% block includes %}
{{ super() }}
#include "{{generated_conversion_include}}"

#include "base/lazy_instance.h"
#include "cobalt/script/exception_state.h"
#include "cobalt/script/mozjs-45/callback_function_conversion.h"
#include "cobalt/script/mozjs-45/conversion_helpers.h"
#include "cobalt/script/mozjs-45/mozjs_callback_function.h"
#include "cobalt/script/mozjs-45/mozjs_exception_state.h"
#include "cobalt/script/mozjs-45/mozjs_global_environment.h"
#include "cobalt/script/mozjs-45/mozjs_property_enumerator.h"
#include "cobalt/script/mozjs-45/mozjs_user_object_holder.h"
#include "cobalt/script/mozjs-45/mozjs_value_handle.h"
#include "cobalt/script/mozjs-45/native_promise.h"
#include "cobalt/script/mozjs-45/proxy_handler.h"
#include "cobalt/script/mozjs-45/type_traits.h"
#include "cobalt/script/mozjs-45/wrapper_factory.h"
#include "cobalt/script/mozjs-45/wrapper_private.h"
#include "cobalt/script/property_enumerator.h"
#include "cobalt/script/sequence.h"
#include "third_party/mozjs-45/js/src/jsapi.h"
{% if is_exception_interface %}
#include "third_party/mozjs-45/js/src/jsexn.h"
{% endif %}
#include "third_party/mozjs-45/js/src/jsfriendapi.h"

{% endblock includes %}

{% block using_directives %}
{{ super() }}
using cobalt::script::CallbackFunction;
using cobalt::script::CallbackInterfaceTraits;
using cobalt::script::ExceptionState;
using cobalt::script::Wrappable;
using cobalt::script::mozjs::FromJSValue;
using cobalt::script::mozjs::InterfaceData;
using cobalt::script::mozjs::MozjsCallbackFunction;
using cobalt::script::mozjs::MozjsExceptionState;
using cobalt::script::mozjs::MozjsGlobalEnvironment;
using cobalt::script::mozjs::MozjsPropertyEnumerator;
using cobalt::script::mozjs::MozjsUserObjectHolder;
using cobalt::script::mozjs::ProxyHandler;
using cobalt::script::mozjs::ToJSValue;
using cobalt::script::mozjs::TypeTraits;
using cobalt::script::mozjs::WrapperFactory;
using cobalt::script::mozjs::WrapperPrivate;
using cobalt::script::mozjs::kConversionFlagClamped;
using cobalt::script::mozjs::kConversionFlagNullable;
using cobalt::script::mozjs::kConversionFlagRestricted;
using cobalt::script::mozjs::kConversionFlagTreatNullAsEmptyString;
using cobalt::script::mozjs::kConversionFlagTreatUndefinedAsEmptyString;
using cobalt::script::mozjs::kConversionFlagObjectOnly;
using cobalt::script::mozjs::kNoConversionFlags;
{% endblock using_directives %}

{% block enumeration_declarations %}
{% if enumerations|length %}
// Declare and define these in the same namespace that the other overloads
// were brought into with the using declaration.
{% for enumeration in enumerations %}
void ToJSValue(JSContext* context, {{impl_class}}::{{enumeration.name}} in_enum,
               JS::MutableHandleValue out_value);
void FromJSValue(JSContext* context, JS::HandleValue value,
                 int conversion_flags, ExceptionState* exception_state,
                 {{impl_class}}::{{enumeration.name}}* out_enum);
{% endfor %}
{% endif %}
{% endblock enumeration_declarations %}

{% block top_level_unnamed_namespace %}
{% if is_global_interface %}
JSObject* DummyFunctor(
    JSContext* context, const scoped_refptr<Wrappable>& wrappable) {
  NOTREACHED();
  return NULL;
}
{% endif %}
{% endblock top_level_unnamed_namespace %}

{% block implementation %}

namespace {

{% if named_property_getter %}

bool IsSupportedNamedProperty(JSContext* context, JS::HandleObject object,
                              const std::string& property_name) {
{{ get_impl_class_instance(impl_class) }}
  return impl->CanQueryNamedProperty(property_name);
}

void EnumerateSupportedNames(JSContext* context, JS::HandleObject object,
                             JS::AutoIdVector* properties) {
{{ get_impl_class_instance(impl_class) }}
  MozjsPropertyEnumerator enumerator(context, properties);
  impl->EnumerateNamedProperties(&enumerator);
}

bool GetNamedProperty(
    JSContext* context, JS::HandleObject object, JS::HandleId id,
    JS::MutableHandleValue vp) {
  JS::RootedValue id_value(context);
  if (!JS_IdToValue(context, id, &id_value)) {
    NOTREACHED();
    return false;
  }

{{ nonstatic_function_prologue(impl_class) }}
  std::string property_name;
  FromJSValue(context, id_value, kNoConversionFlags, &exception_state,
              &property_name);
  if (exception_state.is_exception_set()) {
    // The ID should be an integer or a string, so we shouldn't have any
    // exceptions converting to string.
    NOTREACHED();
    return false;
  }
{{ call_cobalt_function(impl_class, named_property_getter.type,
                        named_property_getter.name, ["property_name"],
                        named_property_getter.raises_exception,
                        named_property_getter.call_with) }}
  if (!exception_state.is_exception_set()) {
    vp.set(result_value);
  }
  return !exception_state.is_exception_set();
}

{% endif %}

{% if named_property_setter %}

bool SetNamedProperty(
  JSContext* context, JS::HandleObject object, JS::HandleId id,
  JS::MutableHandleValue vp, JS::ObjectOpResult& object_op_result) {
  JS::RootedValue id_value(context);
  if (!JS_IdToValue(context, id, &id_value)) {
    NOTREACHED();
    return false;
  }
{{ nonstatic_function_prologue(impl_class) }}
  std::string property_name;
  FromJSValue(context, id_value, kNoConversionFlags, &exception_state,
              &property_name);
  if (exception_state.is_exception_set()) {
    // The ID should be an integer or a string, so we shouldn't have any
    // exceptions converting to string.
    NOTREACHED();
    return false;
  }
  TypeTraits<{{named_property_setter.type}} >::ConversionType value;
  FromJSValue(context, vp, {{named_property_setter.conversion_flags}},
              &exception_state, &value);
  if (exception_state.is_exception_set()) {
    return false;
  }
{{ call_cobalt_function(impl_class, "void",
                        named_property_setter.name, ["property_name", "value"],
                        named_property_setter.raises_exception,
                        named_property_setter.call_with) }}

  if (!exception_state.is_exception_set()) {
    return object_op_result.succeed();
  } else {
    return false;
  }
}

{% endif %}

{% if named_property_deleter %}

bool DeleteNamedProperty(JSContext* context, JS::HandleObject object,
                         const std::string& property_name) {
{{ nonstatic_function_prologue(impl_class) }}
{{ call_cobalt_function(impl_class, "void",
                        named_property_deleter.name, ["property_name"],
                        named_property_deleter.raises_exception,
                        named_property_deleter.call_with) }}
  return !exception_state.is_exception_set();
}

{% endif %}

{% if indexed_property_getter %}

bool IsSupportedIndexProperty(JSContext* context, JS::HandleObject object,
                              uint32_t index) {
{{ get_impl_class_instance(impl_class) }}
  return index < impl->length();
}

void EnumerateSupportedIndexes(JSContext* context, JS::HandleObject object,
                               JS::AutoIdVector* properties) {
{{ get_impl_class_instance(impl_class) }}
  const uint32_t kNumIndexedProperties = impl->length();
  for (uint32_t i = 0; i < kNumIndexedProperties; ++i) {
    properties->append(INT_TO_JSID(i));
  }
}

bool GetIndexedProperty(
    JSContext* context, JS::HandleObject object, JS::HandleId id,
    JS::MutableHandleValue vp) {
  JS::RootedValue id_value(context);
  if (!JS_IdToValue(context, id, &id_value)) {
    NOTREACHED();
    return false;
  }
{{ nonstatic_function_prologue(impl_class) }}
  uint32_t index;
  FromJSValue(context, id_value, kNoConversionFlags, &exception_state, &index);
  if (exception_state.is_exception_set()) {
    // The ID should be an integer or a string, so we shouldn't have any
    // exceptions converting to string.
    NOTREACHED();
    return false;
  }
{{ call_cobalt_function(impl_class, indexed_property_getter.type,
                        indexed_property_getter.name, ["index"],
                        indexed_property_getter.raises_exception,
                        indexed_property_getter.call_with) }}
  if (!exception_state.is_exception_set()) {
    vp.set(result_value);
  }
  return !exception_state.is_exception_set();
}

{% endif %}

{% if indexed_property_setter %}

bool SetIndexedProperty(
  JSContext* context, JS::HandleObject object, JS::HandleId id,
  JS::MutableHandleValue vp, JS::ObjectOpResult& object_op_result) {
  JS::RootedValue id_value(context);
  if (!JS_IdToValue(context, id, &id_value)) {
    NOTREACHED();
    return false;
  }
{{ nonstatic_function_prologue(impl_class) }}
  uint32_t index;
  FromJSValue(context, id_value, kNoConversionFlags, &exception_state, &index);
  if (exception_state.is_exception_set()) {
    // The ID should be an integer or a string, so we shouldn't have any
    // exceptions converting to string.
    NOTREACHED();
    return false;
  }
  TypeTraits<{{indexed_property_setter.type}} >::ConversionType value;
  FromJSValue(context, vp, {{indexed_property_setter.conversion_flags}},
              &exception_state, &value);
  if (exception_state.is_exception_set()) {
    return false;
  }
{{ call_cobalt_function(impl_class, "void",
                        indexed_property_setter.name, ["index", "value"],
                        indexed_property_setter.raises_exception,
                        indexed_property_setter.call_with) }}
  if (!exception_state.is_exception_set()) {
    return object_op_result.succeed();
  } else {
    return false;
  }
}

{% endif %}

{% if indexed_property_deleter %}

bool DeleteIndexedProperty(
    JSContext* context, JS::HandleObject object, uint32_t index) {
{{ nonstatic_function_prologue(impl_class) }}
{{ call_cobalt_function(impl_class, "void",
                        indexed_property_deleter.name, ["index"],
                        indexed_property_deleter.raises_exception,
                        indexed_property_deleter.call_with) }}
  return !exception_state.is_exception_set();
}

{% endif %}

class {{binding_class}}Handler : public ProxyHandler {
 public:
  {{binding_class}}Handler()
      : ProxyHandler(indexed_property_hooks, named_property_hooks) {}

 private:
  static NamedPropertyHooks named_property_hooks;
  static IndexedPropertyHooks indexed_property_hooks;
};

ProxyHandler::NamedPropertyHooks
{{binding_class}}Handler::named_property_hooks = {
  {{ "IsSupportedNamedProperty" if named_property_getter else "NULL" }},
  {{ "EnumerateSupportedNames" if named_property_getter else "NULL" }},
  {{ "GetNamedProperty" if named_property_getter else "NULL" }},
  {{ "SetNamedProperty" if named_property_setter else "NULL" }},
  {{ "DeleteNamedProperty" if named_property_deleter else "NULL" }},
};

ProxyHandler::IndexedPropertyHooks
{{binding_class}}Handler::indexed_property_hooks = {
  {{ "IsSupportedIndexProperty" if indexed_property_getter else "NULL" }},
  {{ "EnumerateSupportedIndexes" if indexed_property_getter else "NULL" }},
  {{ "GetIndexedProperty" if indexed_property_getter else "NULL" }},
  {{ "SetIndexedProperty" if indexed_property_setter else "NULL" }},
  {{ "DeleteIndexedProperty" if indexed_property_deleter else "NULL" }},
};

static base::LazyInstance<{{binding_class}}Handler>
    proxy_handler;

{% if constructor %}
bool Constructor(JSContext* context, unsigned int argc, JS::Value* vp);
{% else %}
bool DummyConstructor(JSContext* context, unsigned int argc, JS::Value* vp) {
  MozjsExceptionState exception(context);
  exception.SetSimpleException(
      script::kTypeError, "{{interface_name}} is not constructible.");
  return false;
}
{% endif %}

{% for constant in constants %}
bool get_{{constant.idl_name}}(
    JSContext* context, unsigned argc, JS::Value* vp) {
{% if constant.can_use_compile_assert %}
  COMPILE_ASSERT({{impl_class}}::{{constant.name}} == {{constant.value}},
                 ValueFor{{impl_class}}_{{constant.name}}DoesNotMatchIDL);
{% else %}
  DCHECK_EQ({{constant.value}}, {{impl_class}}::{{constant.name}}) <<
      "The value for {{impl_class}}::{{constant.name}} does not match "
      "the value in the interface definition.";
{% endif %}
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  if (!args.thisv().isObject()) {
    MozjsExceptionState exception(context);
    exception.SetSimpleException(script::kTypeError, "Invalid this.");
    return false;
  }
  JS::RootedObject object(context, &args.thisv().toObject());
  MozjsExceptionState exception_state(context);
  JS::RootedValue result_value(context);
  ToJSValue(context, {{constant.value}}, &result_value);
  if (!exception_state.is_exception_set()) {
    args.rval().set(result_value);
  }
  return !exception_state.is_exception_set();
}
{% endfor %}

bool HasInstance(JSContext *context, JS::HandleObject type,
                   JS::MutableHandleValue vp, bool *success) {
  JS::RootedObject global_object(
      context, JS_GetGlobalForObject(context, type));
  DCHECK(global_object);

  JS::RootedObject prototype(
      context, {{binding_class}}::GetPrototype(context, global_object));

  // |IsDelegate| walks the prototype chain of an object returning true if
  // .prototype is found.
  bool is_delegate;
  if (!IsDelegate(context, prototype, vp, &is_delegate)) {
    *success = false;
    return false;
  }

  *success = is_delegate;
  return true;
}

const JSClass instance_class_definition = {
    "{{interface_name}}",
    {{ "JSCLASS_GLOBAL_FLAGS" if is_global_interface else 0 }} | JSCLASS_HAS_PRIVATE,
    NULL,  // addProperty
    NULL,  // delProperty
    NULL,  // getProperty
    NULL,  // setProperty
    NULL,  // enumerate
    NULL,  // resolve
    NULL,  // mayResolve
    &WrapperPrivate::Finalizer,  // finalize
    NULL,  // call
    NULL,  // hasInstance
    NULL,  // construct
    {{ "JS_GlobalObjectTraceHook" if is_global_interface else "&WrapperPrivate::Trace" }},  // trace
};

const JSClass prototype_class_definition = {
    "{{interface_name}}Prototype",
};

const JSClass interface_object_class_definition = {
    "{{interface_name}}Constructor",
    0,
    NULL,  // addProperty
    NULL,  // delProperty
    NULL,  // getProperty
    NULL,  // setProperty
    NULL,  // enumerate
    NULL,  // resolve
    NULL,  // mayResolve
    NULL,  // finalize
    NULL,  // call
    &HasInstance,
{% if constructor %}
    Constructor,
{% else %}
    NULL,
{% endif %}
};

{% for attribute in attributes + static_attributes %}
{% if attribute.conditional %}
#if defined({{attribute.conditional}})
{% endif %}
{% if attribute.is_constructor_attribute %}
bool get_{{attribute.idl_name}}(
    JSContext* context, unsigned argc, JS::Value* vp) {
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  if (!args.thisv().isObject()) {
    MozjsExceptionState exception(context);
    exception.SetSimpleException(script::kTypeError, "Invalid this.");
    return false;
  }
  JS::RootedObject object(context, &args.thisv().toObject());
  JS::RootedObject global_object(
    context, JS_GetGlobalForObject(context, object));
  DCHECK(global_object);
  JS::RootedObject interface_object(context,
      Mozjs{{attribute.interface_name}}::GetInterfaceObject(
          context, global_object));
  args.rval().setObject(*interface_object);
  return true;
}
{% else %}
{% if attribute.is_static %}
bool staticget_{{attribute.idl_name}}(
    JSContext* context, unsigned argc, JS::Value* vp) {
{{ static_function_prologue() -}}
{% else %}
bool get_{{attribute.idl_name}}(
    JSContext* context, unsigned argc, JS::Value* vp) {
{% endif %}
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  if (!args.thisv().isObject()) {
    MozjsExceptionState exception(context);
    exception.SetSimpleException(script::kTypeError, "Invalid this.");
    return false;
  }
  JS::RootedObject object(context, &args.thisv().toObject());
{% if not attribute.is_static %}
{{ check_if_object_implements_interface() }}
{{ nonstatic_function_prologue(impl_class) }}
{% endif %}
{{ call_cobalt_function(impl_class, attribute.type,
                        attribute.getter_function_name, [],
                        attribute.raises_exception, attribute.call_with,
                        attribute.is_static) }}
  if (!exception_state.is_exception_set()) {
    args.rval().set(result_value);
  }
  return !exception_state.is_exception_set();
}

{% if attribute.has_setter %}
{% if attribute.is_static %}
bool staticset_{{attribute.idl_name}}(
  JSContext* context, unsigned argc, JS::Value* vp) {
{% else %}
bool set_{{attribute.idl_name}}(
    JSContext* context, unsigned argc, JS::Value* vp) {
{% endif %}

  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  if (!args.thisv().isObject()) {
    MozjsExceptionState exception(context);
    exception.SetSimpleException(script::kTypeError, "Invalid this.");
    return false;
  }
  JS::RootedObject object(context, &args.thisv().toObject());

{% if attribute.is_static %}
{{ static_function_prologue() }}
{% else %}
{{ check_if_object_implements_interface() }}
{{ nonstatic_function_prologue(impl_class)}}
{% endif %} {#- attribute.is_static #}
{{ set_attribute_implementation(attribute, impl_class) -}}
}
{% endif %} {#- attribute.has_setter #}

{% endif %}
{% if attribute.conditional %}
#endif  // {{attribute.conditional}}
{% endif %} {#- attribute.is_constructor_attribute #}
{% endfor %}

{%- for operation in operations + static_operations %}
{% if operation.conditional %}
#if defined({{operation.conditional}})
{% endif %}
{% set boundFunctionPrefix = "staticfcn_" if operation.is_static else "fcn_" %}
{% for overload in operation.overloads if operation.overloads|length > 1 %}
bool {{boundFunctionPrefix}}{{operation.idl_name}}{{overload.overload_index}}(
    JSContext* context, uint32_t argc, JS::Value *vp) {
{{ function_implementation(overload) -}}
}
{% endfor %}

bool {{boundFunctionPrefix}}{{operation.idl_name}}(
    JSContext* context, uint32_t argc, JS::Value *vp) {
{% if operation.overloads|length == 1 %}
{{ function_implementation(operation.overloads[0]) -}}
{% else %}
{{ overload_resolution_implementation(
      operation, boundFunctionPrefix + operation.idl_name) }}
{% endif %}
}

{% if operation.conditional %}
#endif  // {{operation.conditional}}
{% endif %}
{% endfor %}

{% if stringifier %}
bool Stringifier(JSContext* context, unsigned argc, JS::Value *vp) {
  MozjsExceptionState exception_state(context);
  // Compute the 'this' value.
  JS::RootedValue this_value(context, JS_ComputeThis(context, vp));
  // 'this' should be an object.
  JS::RootedObject object(context);

  if (JS_TypeOfValue(context, this_value) != JSTYPE_OBJECT) {
    return false;
  }
  if (!JS_ValueToObject(context, this_value, &object)) {
    NOTREACHED();
    return false;
  }

  {{ check_if_object_implements_interface() }}

  WrapperPrivate* wrapper_private =
      WrapperPrivate::GetFromObject(context, object);

  // |WrapperPrivate::GetFromObject| can fail if |object| is not a |Wrapper|
  // object.
  if (!wrapper_private) {
    exception_state.SetSimpleException(cobalt::script::kStringifierProblem);
    return false;
  }

  {{impl_class}}* impl =
      wrapper_private->wrappable<{{impl_class}}>().get();
  if (!impl) {
    exception_state.SetSimpleException(cobalt::script::kStringifierProblem);
    NOTREACHED();
    return false;
  }
  std::string stringified = impl->{{stringifier.name}}();
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  JS::RootedString rooted_string(context,
      JS_NewStringCopyN(context, stringified.c_str(), stringified.length()));
  args.rval().set(JS::StringValue(rooted_string));
  return true;
}
{% endif %}

const JSPropertySpec prototype_properties[] = {
{% for constant in constants %}
  {
      "{{constant.idl_name}}",
      JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_ENUMERATE,
      { { &get_{{constant.idl_name}}, NULL } },
      JSNATIVE_WRAPPER(NULL)
  },
{% endfor %}

{% for attribute in attributes if not attribute.is_constructor_attribute %}
{% if attribute.conditional %}
#if defined({{attribute.conditional}})
{% endif %}
{% if attribute.has_setter %}
  {  // Read/Write property
    "{{attribute.idl_name}}",
    JSPROP_SHARED | JSPROP_ENUMERATE,
    { { &get_{{attribute.idl_name}}, NULL } },
    { { &set_{{attribute.idl_name}}, NULL } },
  },
{% else %}
  {  // Readonly attribute
    "{{attribute.idl_name}}",
    JSPROP_SHARED | JSPROP_ENUMERATE,
    { { &get_{{attribute.idl_name}}, NULL } },
    JSNATIVE_WRAPPER(NULL),
  },
{% endif %}
{% if attribute.conditional %}
#endif  // {{attribute.conditional}}
{% endif %}
{% endfor %}
  JS_PS_END
};

const JSFunctionSpec prototype_functions[] = {
{% if stringifier %}
  JS_FNSPEC("toString", Stringifier, NULL, 0, JSPROP_ENUMERATE, NULL),
{% endif %}
{% for operation in operations %}
{% if operation.conditional %}
#if defined({{operation.conditional}})
{% endif %}
  JS_FNSPEC(
      "{{ operation.idl_name }}", fcn_{{operation.idl_name}}, NULL,
      {{ operation.length }}, JSPROP_ENUMERATE, NULL),
{% if operation.conditional %}
#endif  // {{operation.conditional}}
{% endif %}
{% endfor %}
  JS_FS_END
};

const JSPropertySpec interface_object_properties[] = {
{% for constant in constants %}
  {
    "{{constant.idl_name}}",
    JSPROP_SHARED | JSPROP_ENUMERATE,
    { { &get_{{constant.idl_name}}, NULL } },
    JSNATIVE_WRAPPER(NULL),
  },
{% endfor %}

{% for attribute in static_attributes %}
{% if attribute.conditional %}
#if defined({{attribute.conditional}})
{% endif %}
{% if attribute.has_setter %}
  {  // Static read/write attribute.
    "{{attribute.idl_name}}",
    JSPROP_SHARED | JSPROP_ENUMERATE,
    { { &staticget_{{attribute.idl_name}}, NULL } },
    { { &staticset_{{attribute.idl_name}}, NULL } },
  },
{% else %}
  {  // Static readonly attribute.
    "{{attribute.idl_name}}",
    JSPROP_SHARED | JSPROP_ENUMERATE,
    { { &staticget_{{attribute.idl_name}} } },
    JSNATIVE_WRAPPER(NULL),
  },
{% endif %}
{% if attribute.conditional %}
#endif  // {{attribute.conditional}}
{% endif %}
{% endfor %}
  JS_PS_END
};

const JSFunctionSpec interface_object_functions[] = {
{% for operation in static_operations %}
{% if operation.conditional %}
#if defined({{operation.conditional}})
{% endif %}
  JS_FNSPEC(
      "{{ operation.idl_name }}", staticfcn_{{operation.idl_name}}, NULL,
      {{ operation.length }}, JSPROP_ENUMERATE, NULL),
{% if operation.conditional %}
#endif  // {{operation.conditional}}
{% endif %}
{% endfor %}
  JS_FS_END
};

const JSPropertySpec own_properties[] = {
{% for attribute in attributes if attribute.is_constructor_attribute %}
{% if attribute.conditional %}
#if defined({{attribute.conditional}})
{% endif %}
  {  // Constructor attribute
      "{{attribute.idl_name}}",
      JSPROP_SHARED | JSPROP_ENUMERATE,
      { { &get_{{attribute.idl_name}}, NULL } },
      JSNATIVE_WRAPPER(NULL),
  },
{% if attribute.conditional %}
#endif  // {{attribute.conditional}}
{% endif %}
{% endfor %}
  JS_PS_END
};

void InitializePrototypeAndInterfaceObject(
    InterfaceData* interface_data, JSContext* context,
    JS::HandleObject global_object) {
  DCHECK(!interface_data->prototype);
  DCHECK(!interface_data->interface_object);
  DCHECK(JS_IsGlobalObject(global_object));

{% if parent_interface %}
  JS::RootedObject parent_prototype(
      context, {{parent_interface}}::GetPrototype(context, global_object));
  static_assert(
      std::is_base_of<{{parent_interface_name}}, {{interface_name}}>::value,
      "Expected {{interface_name}} to have C++ parent class "
      "{{parent_interface_name}}, because that is its WebIDL parent.");

{% elif is_exception_interface %}
  // Get Error prototype.
  JS::RootedObject parent_prototype(context);
  bool success_check = JS_GetClassPrototype(
      context, js::GetExceptionProtoKey(JSEXN_ERR), &parent_prototype);
  DCHECK(success_check);
{% else %}
  JS::RootedObject parent_prototype(
      context, JS_GetObjectPrototype(context, global_object));
  {% endif %}
  DCHECK(parent_prototype);

  interface_data->prototype = JS_NewObjectWithGivenProto(
    context, &prototype_class_definition, parent_prototype
  );

  JS::RootedObject rooted_prototype(context, interface_data->prototype);
  bool success = JS_DefineProperties(
      context,
      rooted_prototype,
      prototype_properties);

  DCHECK(success);
  success = JS_DefineFunctions(
      context, rooted_prototype, prototype_functions);
  DCHECK(success);

{% if has_interface_object %}
  JS::RootedObject function_prototype(
      context, JS_GetFunctionPrototype(context, global_object));
  DCHECK(function_prototype);

  const char name[] =
      "{{ named_constructor if named_constructor else interface.name }}";

  JSFunction* function = js::NewFunctionWithReserved(
      context,
{% if constructor %}
      Constructor,
      {{constructor.length}},
{% else %}
      DummyConstructor,
      0,
{% endif %}
      JSFUN_CONSTRUCTOR,
      name);
  interface_data->interface_object = JS_GetFunctionObject(function);

  // Add the InterfaceObject.name property.
  JS::RootedObject rooted_interface_object(
      context, interface_data->interface_object);
  JS::RootedValue name_value(context);

  js::SetPrototype(context, rooted_interface_object, function_prototype);

  name_value.setString(JS_NewStringCopyZ(context, name));
  success = JS_DefineProperty(
      context, rooted_interface_object, "name", name_value, JSPROP_READONLY,
      NULL, NULL);
  DCHECK(success);
{% if constructor %}

  // Add the InterfaceObject.length property. It is set to the length of the
  // shortest argument list of all overload constructors.
  JS::RootedValue length_value(context);
  length_value.setInt32({{constructor.length}});
  success = JS_DefineProperty(
      context, rooted_interface_object, "length", length_value,
      JSPROP_READONLY, NULL, NULL);
  DCHECK(success);
{% endif %}

  // Define interface object properties (including constants).
  success = JS_DefineProperties(context, rooted_interface_object,
                                interface_object_properties);
  DCHECK(success);
  // Define interface object functions (static).
  success = JS_DefineFunctions(context, rooted_interface_object,
                               interface_object_functions);
  DCHECK(success);

  // Set the Prototype.constructor and Constructor.prototype properties.
  DCHECK(interface_data->interface_object);
  DCHECK(interface_data->prototype);
  success = JS_LinkConstructorAndPrototype(
      context,
      rooted_interface_object,
      rooted_prototype);
  DCHECK(success);
{% endif %}
}

inline InterfaceData* GetInterfaceData(JSContext* context) {
  const int kInterfaceUniqueId = {{unique_id}};
  MozjsGlobalEnvironment* global_environment =
      static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
  // By convention, the |MozjsGlobalEnvironment| that we are associated with
  // will hold our |InterfaceData| at index |kInterfaceUniqueId|, as we asked
  // for it to be there in the first place, and could not have conflicted with
  // any other interface.
  return global_environment->GetInterfaceData(kInterfaceUniqueId);
}

}  // namespace

{% if is_global_interface %}
JSObject* {{binding_class}}::CreateProxy(
    JSContext* context, const scoped_refptr<Wrappable>& wrappable) {

  InterfaceData* interface_data = GetInterfaceData(context);

  JS::RootedObject global_object(
      context, JS_NewGlobalObject(context,
          &instance_class_definition, NULL,
          JS::FireOnNewGlobalHook,
          JS::CompartmentOptions().setTrace(WrapperPrivate::Trace)));
  DCHECK(global_object);

  // Initialize standard JS constructors prototypes and top-level functions such
  // as Object, isNan, etc.
  JSAutoCompartment auto_compartment(context, global_object);
  bool success = JS_InitStandardClasses(context, global_object);
  DCHECK(success);

  JS::RootedObject prototype(
      context, {{binding_class}}::GetPrototype(context, global_object));
  DCHECK(prototype);
  JS_SetPrototype(context, global_object, prototype);

  JS_SetImmutablePrototype(context, global_object, &success);
  DCHECK(success);

  // Add own properties.
  success = JS_DefineProperties(context, global_object, own_properties);
  DCHECK(success);

  JS::RootedObject proxy(context,
      ProxyHandler::NewProxy(
          context, proxy_handler.Pointer(), global_object, prototype));
  WrapperPrivate::AddPrivateData(context, proxy, wrappable);

  // Set the global object proxy pointer, so we can access the standard classes
  // such as the base Object prototype when looking up our prototype.
  MozjsGlobalEnvironment* global_environment =
      static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
  global_environment->SetGlobalObjectProxyAndWrapper(proxy, wrappable);
  return proxy;
}
{% else %}
// static
JSObject* {{binding_class}}::CreateProxy(
    JSContext* context, const scoped_refptr<Wrappable>& wrappable) {
  DCHECK(MozjsGlobalEnvironment::GetFromContext(context));
  JS::RootedObject global_object(
      context,
      MozjsGlobalEnvironment::GetFromContext(context)->global_object());
  DCHECK(global_object);

  InterfaceData* interface_data = GetInterfaceData(context);
  JS::RootedObject prototype(context, GetPrototype(context, global_object));
  DCHECK(prototype);
  JS::RootedObject new_object(
      context,
      JS_NewObjectWithGivenProto(
          context, &instance_class_definition, prototype));
  DCHECK(new_object);
  JS::RootedObject proxy(context,
      ProxyHandler::NewProxy(
          context, proxy_handler.Pointer(), new_object, prototype));
  WrapperPrivate::AddPrivateData(context, proxy, wrappable);
  return proxy;
}
{% endif %}

// static
const JSClass* {{binding_class}}::PrototypeClass(
      JSContext* context) {
  DCHECK(MozjsGlobalEnvironment::GetFromContext(context));
  JS::RootedObject global_object(
      context,
      MozjsGlobalEnvironment::GetFromContext(context)->global_object());
  DCHECK(global_object);

  JS::RootedObject prototype(context, GetPrototype(context, global_object));
  const JSClass* proto_class = JS_GetClass(prototype);
  return proto_class;
}

// static
JSObject* {{binding_class}}::GetPrototype(
    JSContext* context, JS::HandleObject global_object) {
  DCHECK(JS_IsGlobalObject(global_object));

  InterfaceData* interface_data = GetInterfaceData(context);
  if (!interface_data->prototype) {
    // Create new prototype that has all the props and methods
    InitializePrototypeAndInterfaceObject(
        interface_data, context, global_object);
  }
  DCHECK(interface_data->prototype);
  return interface_data->prototype;
}

{% if has_interface_object %}
// static
JSObject* {{binding_class}}::GetInterfaceObject(
    JSContext* context, JS::HandleObject global_object) {
  DCHECK(JS_IsGlobalObject(global_object));

  InterfaceData* interface_data = GetInterfaceData(context);
  if (!interface_data->interface_object) {
    InitializePrototypeAndInterfaceObject(
        interface_data, context, global_object);
  }
  DCHECK(interface_data->interface_object);
  return interface_data->interface_object;
}
{% endif %} {#- has_interface_object #}

namespace {

{% if constructor %}

{% for overload in constructor.overloads if constructor.overloads|length > 1 %}
bool Constructor{{overload.overload_index}}(
    JSContext* context, unsigned int argc, JS::Value* vp) {
{{ constructor_implementation(overload) -}}
}
{% endfor %}

bool Constructor(JSContext* context, unsigned int argc, JS::Value* vp) {
{% if constructor.overloads|length == 1 %}
{{ constructor_implementation(constructor.overloads[0]) -}}
{% else %}
{{ overload_resolution_implementation(constructor, "Constructor")}}
{% endif %}
}

{% endif %}

}  // namespace

{% endblock implementation %}

{% block create_global_object_impl %}

namespace cobalt {
namespace script {
namespace mozjs {

template <typename GlobalInterface>
void MozjsGlobalEnvironment::CreateGlobalObject(
    const scoped_refptr<GlobalInterface>& global_interface,
    EnvironmentSettings* environment_settings) {
  JSAutoRequest auto_request(context_);
  {{binding_class}}::CreateProxy(context_, global_interface);

  DCHECK(!environment_settings_);
  DCHECK(environment_settings);
  environment_settings_ = environment_settings;
  EvaluateAutomatics();

{% for interface in all_interfaces %}
{% if interface.conditional %}
#if defined({{interface.conditional}})
{% endif %}
{# Pass in a dummy CreateProxy for global interface #}
{% if interface.name == impl_class %}
  wrapper_factory_->RegisterWrappableType(
      {{interface.name}}::{{interface.name}}WrappableType(),
      base::Bind(DummyFunctor),
      base::Bind(Mozjs{{interface.name}}::PrototypeClass));
{% else %}
  wrapper_factory_->RegisterWrappableType(
      {{interface.name}}::{{interface.name}}WrappableType(),
      base::Bind(Mozjs{{interface.name}}::CreateProxy),
      base::Bind(Mozjs{{interface.name}}::PrototypeClass));
{% endif %}
{% if interface.conditional %}
#endif  // defined({{interface.conditional}})
{% endif %}
{% endfor %}

}

}  // namespace mozjs

template<>
void GlobalEnvironment::CreateGlobalObject<{{impl_class}}>(
    const scoped_refptr<{{impl_class}}>& global_interface,
    EnvironmentSettings* environment_settings) {
  base::polymorphic_downcast<MozjsGlobalEnvironment*>(this)->CreateGlobalObject(
      global_interface, environment_settings);
}

}  // namespace script
}  // namespace cobalt

{% endblock create_global_object_impl %}

{%  block enumeration_definitions %}

{% for enumeration in enumerations %}

inline void ToJSValue(
    JSContext* context,
    {{impl_class}}::{{enumeration.name}} in_enum,
    JS::MutableHandleValue out_value) {

  switch (in_enum) {
{% for value, idl_value in enumeration.value_pairs %}
    case {{impl_class}}::{{value}}:
      ToJSValue(context, std::string("{{idl_value}}"), out_value);
      return;
{% endfor %}
    default:
      NOTREACHED();
      out_value.set(JS::UndefinedValue());
  }
}

inline void FromJSValue(JSContext* context, JS::HandleValue value,
                 int conversion_flags, ExceptionState* exception_state,
                 {{impl_class}}::{{enumeration.name}}* out_enum) {
  DCHECK_EQ(0, conversion_flags) << "Unexpected conversion flags.";
  // JSValue -> IDL enum algorithm described here:
  // http://heycam.github.io/webidl/#es-enumeration
  // 1. Let S be the result of calling ToString(V).
  JS::RootedString rooted_string(context, JS::ToString(context, value));

  bool match = false;
// 3. Return the enumeration value of type E that is equal to S.
{% for value, idl_value in enumeration.value_pairs %}
  {{-" else " if not loop.first}}if (JS_StringEqualsAscii(
      context, rooted_string, "{{idl_value}}", &match)
      && match) {
    *out_enum = {{impl_class}}::{{value}};
  }{% endfor %} else {
    // 2. If S is not one of E's enumeration values, then throw a TypeError.
    exception_state->SetSimpleException(cobalt::script::kConvertToEnumFailed);
    return;
  }
}

{% endfor %}

{% endblock enumeration_definitions %}
