{#
 # 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 %}
#include "third_party/WebKit/Source/JavaScriptCore/config.h"

{{ super() }}
#include "cobalt/script/javascriptcore/conversion_helpers.h"
#include "cobalt/script/javascriptcore/jsc_callback_interface_holder.h"
#include "cobalt/script/javascriptcore/jsc_exception_state.h"
#include "cobalt/script/javascriptcore/jsc_global_object.h"
#include "cobalt/script/javascriptcore/util/exception_helpers.h"
{% endblock includes %}

{% block using_directives %}
{{ super() }}
using cobalt::script::javascriptcore::GetCallableForCallbackInterface;
using cobalt::script::javascriptcore::JSCGlobalObject;
using cobalt::script::javascriptcore::JSCExceptionState;
using cobalt::script::javascriptcore::ToJSValue;
using cobalt::script::javascriptcore::util::GetExceptionString;
{% endblock using_directives %}

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

{{binding_class}}::{{binding_class}}(
    JSC::JSObject* implementing_object)
    : implementing_object_(implementing_object) { }

{% 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 {
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(implementing_object_->globalObject());
  JSC::JSGlobalData* global_data = &global_object->globalData();
  JSC::ExecState* exec_state = global_object->globalExec();
  JSC::JSLockHolder lock(*global_data);

  // get callable object
  JSC::JSValue callable;
  JSC::CallData call_data;
  JSC::CallType call_type = GetCallableForCallbackInterface(exec_state,
      implementing_object_, "{{overload.idl_name}}", &callable, &call_data);
  if (call_type == JSC::CallTypeNone) {
    // TypeError
    DLOG(INFO) << "User object was not callable.";
    *had_exception = true;
{% if overload.type == 'void' %}
    return;
{% else %}
    return {{overload.type}}();
{% endif %}
  }

  JSC::JSValue js_this = ToJSValue(global_object, callback_this);

  // Convert args.
  JSC::MarkedArgumentBuffer args;
  {% for arg in overload.arguments %}
  args.append(ToJSValue(global_object, {{arg.name}}));
  {% endfor %}

  // call
  JSC::DynamicGlobalObjectScope global_object_scope(*global_data, global_object);
  JSC::JSValue js_return_value =
      JSC::call(exec_state, callable, call_type, call_data, js_this, args);
  if (exec_state->hadException()) {
    DLOG(WARNING) << "Exception in callback: "
                  << GetExceptionString(exec_state);
    exec_state->clearException();
    *had_exception = true;
{% if overload.type == 'void' %}
    return;
{% else %}
    return {{overload.type}}();
{% endif %}
  }
{% if overload.type != 'void' %}
  JSCExceptionState exception_state(global_object);
  {{overload.type}} cobalt_return_value;
  FromJSValue(exec_state, js_return_value, 0, &exception_state, &cobalt_return_value);

  *had_exception = exception_state.is_exception_set();
  return cobalt_return_value;
{% else %}
  *had_exception = false;
{% endif %}
}
{% endfor %}
{% endfor %}

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