$$ 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 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.

// clang-format off

#ifndef COBALT_SCRIPT_MOZJS_MOZJS_CALLBACK_FUNCTION_H_
#define COBALT_SCRIPT_MOZJS_MOZJS_CALLBACK_FUNCTION_H_

#include "base/logging.h"
#include "cobalt/script/callback_function.h"
#include "cobalt/script/mozjs/conversion_helpers.h"
#include "cobalt/script/mozjs/convert_callback_return_value.h"
#include "cobalt/script/mozjs/util/exception_helpers.h"
#include "cobalt/script/mozjs/util/stack_trace_helpers.h"
#include "cobalt/script/mozjs/weak_heap_object.h"
#include "nb/memory_scope.h"
#include "third_party/mozjs/js/src/jsapi.h"
#include "third_party/mozjs/js/src/jscntxt.h"

namespace cobalt {
namespace script {
namespace mozjs {

// 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 MozjsCallbackFunction;

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


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

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

  explicit MozjsCallbackFunction(JSContext* context, JS::HandleObject function)
      : context_(context), weak_function_(context, function) {
    DCHECK(context_);
    DCHECK(JS_ObjectIsFunction(context_, function));
  }

  explicit MozjsCallbackFunction(JSContext* context, JS::HandleValue function)
      : context_(context), weak_function_(context, function) {
    DCHECK(context_);
    DCHECK(function.isObject());
    DCHECK(JS_ObjectIsFunction(context_, JSVAL_TO_OBJECT(function)));
  }

  CallbackResult<R> Run($for ARG , [[

      typename base::internal::CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]])
      const OVERRIDE {
    ENABLE_JS_STACK_TRACE_IN_SCOPE(context_);
    TRACK_MEMORY_SCOPE("Javascript");
    TRACE_EVENT0("cobalt::script::mozjs", "MozjsCallbackFunction::Run");
    CallbackResult<R> callback_result;
    JSAutoRequest auto_request(context_);
    JS::RootedObject function(context_, weak_function_.GetObject());
    if (!function) {
      DLOG(WARNING) << "Function was garbage collected.";
      callback_result.exception = true;
    } else {
      JSAutoCompartment auto_compartment(context_, function);
      JSExceptionState* previous_exception_state =
          JS_SaveExceptionState(context_);

      // https://www.w3.org/TR/WebIDL/#es-invoking-callback-functions
      // Callback 'this' is set to null, unless overridden by other specifications
      JS::Value this_value(JS::NullValue());
      JS::RootedValue return_value(context_);
      const int kNumArguments = $(ARITY);


$if ARITY > 0 [[
      JS::Value args[$(ARITY)];
      js::SetValueRangeToNull(args, kNumArguments);
      js::AutoValueArray auto_array_rooter(context_, args, kNumArguments);
      $for ARG [[ToJSValue(context_, a$(ARG), auto_array_rooter.handleAt($(ARG - 1)));
      ]]

      JSBool call_result = JS::Call(context_, this_value, function,
          kNumArguments, args, return_value.address());
]] $else [[
      JSBool call_result = JS::Call(context_, this_value, function, 0, NULL,
          return_value.address());
]]

      if (!call_result) {
        DLOG(WARNING) << "Exception in callback: "
                      << util::GetExceptionString(context_);
        callback_result.exception = true;
      } else {
        callback_result = ConvertCallbackReturnValue<R>(context_, return_value);
      }
      JS_RestoreExceptionState(context_, previous_exception_state);
    }
    return callback_result;
  }

  JSObject* handle() const { return weak_function_.GetObject(); }
  const JS::Value& value() const { return weak_function_.GetValue(); }
  bool WasCollected() const { return weak_function_.WasCollected(); }

 private:
  JSContext* context_;
  WeakHeapObject weak_function_;
};

]]

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

}  // namespace mozjs
}  // namespace script
}  // namespace cobalt

#endif  // COBALT_SCRIPT_MOZJS_MOZJS_CALLBACK_FUNCTION_H_
