/*
 * 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.
 */

// This file has been auto-generated by bindings/code_generator_cobalt.py. DO NOT MODIFY!
// Auto-generated from template: bindings/javascriptcore/templates/callback-interface.h.template

// clang-format off


#include "third_party/WebKit/Source/JavaScriptCore/config.h"

#include "JSCSingleOperationInterface.h"
#include "JSCArbitraryInterface.h"
#include "cobalt/bindings/testing/arbitrary_interface.h"

#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"

namespace {
using cobalt::bindings::testing::SingleOperationInterface;
using cobalt::bindings::testing::JSCSingleOperationInterface;
using cobalt::bindings::testing::ArbitraryInterface;
using cobalt::bindings::testing::JSCArbitraryInterface;

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;
}  // namespace

namespace cobalt {
namespace bindings {
namespace testing {

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

base::optional<int32_t > JSCSingleOperationInterface::HandleCallback(
    const scoped_refptr<script::Wrappable>& callback_this,
    const scoped_refptr<ArbitraryInterface>& value,
    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_, "handleCallback", &callable, &call_data);
  if (call_type == JSC::CallTypeNone) {
    // TypeError
    DLOG(INFO) << "User object was not callable.";
    *had_exception = true;
    return base::optional<int32_t >();
  }

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

  // Convert args.
  JSC::MarkedArgumentBuffer args;
  args.append(ToJSValue(global_object, value));

  // 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;
    return base::optional<int32_t >();
  }
  JSCExceptionState exception_state(global_object);
  base::optional<int32_t > 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;
}

}  // namespace bindings
}  // namespace testing
}  // namespace cobalt

