$$ This is a pump file for generating file templates.  Pump is a python
$$ script that is part of the Google Test suite of utilities.  Description
$$ can be found here:
$$
$$ http://code.google.com/p/googletest/wiki/PumpManual
$$

$$ This should be no larger than MAX_ARITY in base/bind.h.pump.
$var MAX_ARITY = 7

// Copyright 2017 The Cobalt Authors. 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.

// clang-format off

#ifndef COBALT_SCRIPT_V8C_V8C_CALLBACK_FUNCTION_H_
#define COBALT_SCRIPT_V8C_V8C_CALLBACK_FUNCTION_H_

#include <string>

#include "base/logging.h"
#include "cobalt/script/callback_function.h"
#include "cobalt/script/v8c/conversion_helpers.h"
#include "cobalt/script/v8c/entry_scope.h"
#include "cobalt/script/v8c/scoped_persistent.h"
#include "nb/memory_scope.h"
#include "v8/include/v8.h"

namespace cobalt {
namespace script {
namespace v8c {

// Helper template functions for Callback functions' return values before being
// returned to Cobalt.
// Converts the return value from JavaScript into the correct Cobalt type, or
// sets the exception bit if conversion fails.
template <typename R>
CallbackResult<R> ConvertCallbackReturnValue(v8::Isolate* isolate,
                                             v8::Local<v8::Value> value) {
  // TODO: Pass conversion flags to callback function return value if
  // appropriate.
  const int kConversionFlags = 0;
  CallbackResult<R> callback_result;
  LoggingExceptionState exception_state;
  FromJSValue(isolate, value, kConversionFlags, &exception_state,
              &callback_result.result);
  callback_result.exception = exception_state.is_exception_set();
  return callback_result;
}

template <>
inline CallbackResult<void> ConvertCallbackReturnValue(v8::Isolate* isolate,
                                                       v8::Local<v8::Value> value) {
  // No conversion necessary.
  return CallbackResult<void>();
}

// First, we forward declare the Callback class template. This informs the
// compiler that the template only has 1 type parameter which is the base
// CallbackFunction template class with parameters.
//
// See base/callback.h.pump for further discussion on this pattern.
template <typename Sig>
class V8cCallbackFunction;

$range ARITY 0..MAX_ARITY
$for ARITY [[
$range ARG 1..ARITY

$if ARITY == 0 [[
template <typename R>
class V8cCallbackFunction<R(void)>
    : public ScopedPersistent<v8::Value>,
      public CallbackFunction<R(void)> {
]] $else [[
template <typename R, $for ARG , [[typename A$(ARG)]]>
class V8cCallbackFunction<R($for ARG , [[A$(ARG)]])>
    : public ScopedPersistent<v8::Value>,
      public CallbackFunction<R($for ARG , [[A$(ARG)]])> {
]]

 public:
  typedef CallbackFunction<R($for ARG , [[A$(ARG)]])> BaseType;

  V8cCallbackFunction() {}
  V8cCallbackFunction(v8::Isolate* isolate, v8::Local<v8::Value> handle)
      : ScopedPersistent(isolate, handle), isolate_(isolate) {}

  CallbackResult<R> Run($for ARG ,
      [[typename CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]])
      const override {
    CallbackResult<R> callback_result;
    DCHECK(!this->IsEmpty());
    if (this->IsEmpty()) {
      DLOG(WARNING) << "Function was garbage collected.";
      callback_result.exception = true;
      return callback_result;
    }

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

    // https://www.w3.org/TR/WebIDL/#es-invoking-callback-functions
    // Callback 'this' is set to null, unless overridden by other specifications
    v8::Local<v8::Value> this_value = v8::Null(isolate_);
    v8::Local<v8::Value> function = this->NewLocal(isolate_);
    v8::MaybeLocal<v8::Object> maybe_function_as_object = function->ToObject(context);
    v8::Local<v8::Object> function_as_object;
    if (!maybe_function_as_object.ToLocal(&function_as_object)) {
      DLOG(WARNING) << "Unexpected failure converting function to object.";
      callback_result.exception = true;
      return callback_result;
    }

    const int argc = $(ARITY);

$if ARITY > 0 [[
    v8::Local<v8::Value> argv[argc];
    $for ARG [[ToJSValue(isolate_, a$(ARG), &argv[$(ARG - 1)]);
    ]]
]] $else [[
    v8::Local<v8::Value>* argv = nullptr;
]]

    v8::MaybeLocal<v8::Value> maybe_return_value = function_as_object->CallAsFunction(context, this_value, argc, argv);
    v8::Local<v8::Value> return_value;
    if (!maybe_return_value.ToLocal(&return_value)) {
      std::string description;
      v8::Local<v8::Value> stack;
      if (try_catch.StackTrace(context).ToLocal(&stack)) {
        description = *v8::String::Utf8Value(isolate_, stack);
      } else {
        description = *v8::String::Utf8Value(isolate_, try_catch.Exception());
      }
      if (description.empty()) description = "Unknown exception";
      // TODO: Send the description to the console instead of logging it.
      LOG(ERROR) << description;
      callback_result.exception = true;
    } else {
      callback_result = ConvertCallbackReturnValue<R>(isolate_, return_value);
    }

    return callback_result;
  }

 private:
  v8::Isolate* isolate_;
};

]]

template <typename Signature>
struct TypeTraits<CallbackFunction<Signature> > {
  typedef V8cUserObjectHolder<V8cCallbackFunction<Signature> > ConversionType;
  typedef const ScriptValue<CallbackFunction<Signature> >* ReturnType;
};

}  // namespace v8c
}  // namespace script
}  // namespace cobalt

#endif  // COBALT_SCRIPT_V8C_V8C_CALLBACK_FUNCTION_H_
