{#
 # 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.
 #}
{% extends "callback-interface-base.cc.template" %}

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

#include "cobalt/script/logging_exception_state.h"
#include "cobalt/script/mozjs-45/conversion_helpers.h"
#include "cobalt/script/mozjs-45/mozjs_callback_interface.h"
#include "cobalt/script/mozjs-45/util/exception_helpers.h"
#include "third_party/mozjs-45/js/src/jsapi.h"
#include "third_party/mozjs-45/js/src/jscntxt.h"
{% endblock includes %}

{% block using_directives %}
{{ super() }}
using cobalt::script::LoggingExceptionState;
using cobalt::script::mozjs::FromJSValue;
using cobalt::script::mozjs::GetCallableForCallbackInterface;
using cobalt::script::mozjs::ToJSValue;
using cobalt::script::mozjs::util::GetExceptionString;
{% endblock using_directives %}

{% block implementation %}
{% for component in components %}
namespace {{component}} {
{% endfor %}

{{binding_class}}::{{binding_class}}(
    JSContext* context,
    JS::HandleObject implementing_object)
    : context_(context),
      implementing_object_(context, implementing_object) { }

{{binding_class}}::{{binding_class}}(
    JSContext* context,
    JS::HandleValue implementing_object_value)
    : context_(context),
      implementing_object_(context, implementing_object_value) { }

{% for operation in operations %}
{% for overload in operation.overloads %}
{{overload.type}} {{binding_class}}::{{overload.name}}(
    const scoped_refptr<script::Wrappable>& callback_this,
  {% for arg in overload.arguments %}
    {{arg.arg_type}} {{arg.name}},
  {% endfor %}
    bool* had_exception) const {
  bool success = false;
{% if overload.type != 'void' %}
  {{overload.type}} cobalt_return_value;
{% endif %}
  JSAutoRequest auto_request(context_);
  JSExceptionState* previous_exception_state = JS_SaveExceptionState(context_);

  // This could be set to NULL if it was garbage collected.
  JS::RootedObject implementing_object(context_, implementing_object_.GetObject());
  DLOG_IF(WARNING, !implementing_object) << "Implementing object is NULL.";
  if (implementing_object) {
    JSAutoCompartment auto_compartment(context_, implementing_object);

    // Get callable object.
    JS::RootedValue callable(context_);
    if (GetCallableForCallbackInterface(context_, implementing_object,
                                        "{{overload.idl_name}}", &callable)) {
      // Convert the callback_this to a JSValue.
      JS::RootedValue this_value(context_);
      ToJSValue(context_, callback_this, &this_value);

      // Convert arguments.
      const int kNumArguments = {{overload.arguments|length}};
      JS::AutoValueArray<kNumArguments> args(context_);

{% for arg in overload.arguments %}
      ToJSValue(context_, {{arg.name}}, args[{{loop.index0}}]);
{% endfor %}

      // Call the function.
      JS::RootedValue return_value(context_);
      JS::RootedFunction function(
          context_, JS_ValueToFunction(context_, callable));
      DCHECK(function);
      success = JS::Call(context_, this_value, function, args, &return_value);
      DLOG_IF(WARNING, !success) << "Exception in callback: "
                                 << GetExceptionString(context_);
{% if overload.type != 'void' %}
      if (success) {
        LoggingExceptionState exception_state;
        FromJSValue(context_, return_value, 0, &exception_state,
                    &cobalt_return_value);
        success = !exception_state.is_exception_set();
      }
{% endif %}
    }
  }

  *had_exception = !success;
  JS_RestoreExceptionState(context_, previous_exception_state);
{% if overload.type != 'void' %}
  return cobalt_return_value;
{% endif %}
}
{% endfor %}
{% endfor %}

{% for component in components|reverse %}
}  // namespace {{component}}
{% endfor %}
{% endblock implementation %}
