{#
 # Copyright 2017 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/v8c/entry_scope.h"
#include "cobalt/script/v8c/v8c_callback_interface.h"
#include "cobalt/script/v8c/v8c_global_environment.h"
#include "v8/include/v8.h"
{% endblock includes %}

{% block using_directives %}
{{ super() }}
using cobalt::script::LoggingExceptionState;
using cobalt::script::v8c::EntryScope;
using cobalt::script::v8c::FromJSValue;
using cobalt::script::v8c::GetCallableForCallbackInterface;
using cobalt::script::v8c::ToJSValue;
using cobalt::script::v8c::V8cGlobalEnvironment;
{% endblock using_directives %}

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

{% 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 {
{% if overload.type != 'void' %}
  {{overload.type}} cobalt_return_value;
{% endif %}

  DCHECK(!this->IsEmpty());
  DCHECK(isolate_);

  EntryScope entry_scope(isolate_);
  v8::Local<v8::Context> context = isolate_->GetCurrentContext();

  v8::MaybeLocal<v8::Object> maybe_implementing_object = this->NewLocal(isolate_)->ToObject(context);
  v8::Local<v8::Object> implementing_object;
  if (!maybe_implementing_object.ToLocal(&implementing_object)) {
    *had_exception = true;
    return cobalt_return_value;
  }

  v8::MaybeLocal<v8::Object> maybe_callable =
      GetCallableForCallbackInterface(isolate_, implementing_object, "{{overload.idl_name}}");
  v8::Local<v8::Object> callable;
  if (!maybe_callable.ToLocal(&callable)) {
    NOTIMPLEMENTED();
    *had_exception = true;
    return cobalt_return_value;
  }
  DCHECK(callable->IsCallable());

  v8::Local<v8::Value> this_value;
  ToJSValue(isolate_, callback_this, &this_value);

  const int kNumArguments = {{overload.arguments|length}};
  v8::Local<v8::Value> argv[kNumArguments];

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

  v8::MaybeLocal<v8::Value> maybe_return_value =
      callable->CallAsFunction(isolate_->GetCurrentContext(), this_value, kNumArguments, argv);
  v8::Local<v8::Value> return_value;
  if (!maybe_return_value.ToLocal(&return_value)) {
    *had_exception = true;
  return cobalt_return_value;
  }

  LoggingExceptionState exception_state;
  FromJSValue(isolate_, return_value, 0, &exception_state, &cobalt_return_value);
  if (exception_state.is_exception_set()) {
    *had_exception = true;
  }

{% if overload.type != 'void' %}
  return cobalt_return_value;
{% endif %}

}
{% endfor %}
{% endfor %}

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