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

#ifndef COBALT_SCRIPT_V8C_NATIVE_PROMISE_H_
#define COBALT_SCRIPT_V8C_NATIVE_PROMISE_H_

#include <memory>

#include "base/logging.h"
#include "base/threading/thread_checker.h"
#include "cobalt/script/promise.h"
#include "cobalt/script/v8c/conversion_helpers.h"
#include "cobalt/script/v8c/entry_scope.h"
#include "cobalt/script/v8c/scoped_persistent.h"
#include "cobalt/script/v8c/script_promise.h"
#include "cobalt/script/v8c/type_traits.h"
#include "cobalt/script/v8c/v8c_exception_state.h"
#include "cobalt/script/v8c/v8c_user_object_holder.h"
#include "v8/include/v8.h"

namespace cobalt {
namespace script {
namespace v8c {

// TODO: This lives here instead of conversion_helpers.h because right now
// |PromiseResultUndefined| is specific to promises.  In the long run, we plan
// on abstracting all JavaScript value types, and should just use however that
// abstraction exposes "undefined" here instead.
inline void ToJSValue(v8::Isolate* isolate,
                      const PromiseResultUndefined& in_undefined,
                      v8::Local<v8::Value>* out_value) {
  *out_value = v8::Undefined(isolate);
}

// Shared functionality for NativePromise<T>.
template <typename T>
class NativePromise : public ScriptPromise<T> {
 public:
  // ScriptValue boilerplate.
  typedef Promise<T> BaseType;

  // Handle special case T=void, by swapping the input parameter |T| for
  // |PromiseResultUndefined|. Combined with how |Promise| handles this
  // special case, we're left with something like:
  //
  //   NativePromise<T>    ->            Promise<T>
  //                                         ^
  //                                         | (T=PromiseResultUndefined)
  //                                        /
  //   NativePromise<void> -> Promise<void>
  //
  using ResolveType =
      typename std::conditional<std::is_same<T, void>::value,
                                PromiseResultUndefined, T>::type;

  NativePromise(v8::Isolate* isolate, v8::Local<v8::Value> resolver)
      : ScriptPromise<T>(isolate, resolver) {
    DCHECK(resolver->IsPromise());
  }

  void Resolve(const ResolveType& value) const override {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DCHECK(!this->IsEmpty());
    DCHECK(this->State() == PromiseState::kPending);
    EntryScope entry_scope(this->isolate());
    v8::Local<v8::Context> context = this->isolate()->GetCurrentContext();

    v8::Local<v8::Promise::Resolver> promise_resolver = this->resolver();
    v8::Local<v8::Value> converted_value;
    ToJSValue(this->isolate(), value, &converted_value);
    v8::Maybe<bool> reject_result =
        promise_resolver->Resolve(context, converted_value);
    DCHECK(reject_result.FromJust());
  }

  void Reject() const override {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DCHECK(!this->IsEmpty());
    DCHECK(this->State() == PromiseState::kPending);
    EntryScope entry_scope(this->isolate());
    v8::Local<v8::Context> context = this->isolate()->GetCurrentContext();

    v8::Local<v8::Promise::Resolver> promise_resolver = this->resolver();
    v8::Maybe<bool> reject_result =
        promise_resolver->Reject(context, v8::Undefined(this->isolate()));
    DCHECK(reject_result.FromJust());
  }

  void Reject(SimpleExceptionType exception) const override {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DCHECK(!this->IsEmpty());
    DCHECK(this->State() == PromiseState::kPending);
    EntryScope entry_scope(this->isolate());
    v8::Local<v8::Context> context = this->isolate()->GetCurrentContext();

    v8::Local<v8::Promise::Resolver> promise_resolver = this->resolver();
    v8::Local<v8::Value> error_result =
        CreateErrorObject(this->isolate(), exception);
    v8::Maybe<bool> reject_result =
        promise_resolver->Reject(context, error_result);
    DCHECK(reject_result.FromJust());
  }

  void Reject(const scoped_refptr<ScriptException>& result) const override {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DCHECK(!this->IsEmpty());
    DCHECK(this->State() == PromiseState::kPending);
    EntryScope entry_scope(this->isolate());
    v8::Local<v8::Context> context = this->isolate()->GetCurrentContext();

    v8::Local<v8::Promise::Resolver> promise_resolver = this->resolver();
    v8::Local<v8::Value> converted_result;
    ToJSValue(this->isolate(), result, &converted_result);
    v8::Maybe<bool> reject_result =
        promise_resolver->Reject(context, converted_result);
    DCHECK(reject_result.FromJust());
  }

 private:
  // Thread checker ensures all calls to the Promise are made from the same
  // thread that it is created in.
  THREAD_CHECKER(thread_checker_);
};

template <typename T>
struct TypeTraits<NativePromise<T>> {
  typedef V8cUserObjectHolder<NativePromise<T>> ConversionType;
  typedef const ScriptValue<Promise<T>>* ReturnType;
};

// Promise<T> -> JSValue
// Note that JSValue -> Promise<T> is not yet supported.
template <typename T>
inline void ToJSValue(v8::Isolate* isolate,
                      const ScriptValue<Promise<T>>* promise_holder,
                      v8::Local<v8::Value>* out_value) {
  if (!promise_holder) {
    *out_value = v8::Null(isolate);
    return;
  }

  const V8cUserObjectHolder<NativePromise<T>>* user_object_holder =
      base::polymorphic_downcast<const V8cUserObjectHolder<NativePromise<T>>*>(
          promise_holder);
  const NativePromise<T>* native_promise =
      base::polymorphic_downcast<const NativePromise<T>*>(
          user_object_holder->GetValue());
  DCHECK(native_promise);
  *out_value = native_promise->promise();
}

// Explicitly defer to the const version here so that a more generic non-const
// version of this function does not get called instead, in the case that
// |promise_holder| is not const.
template <typename T>
inline void ToJSValue(v8::Isolate* isolate,
                      ScriptValue<Promise<T>>* promise_holder,
                      v8::Local<v8::Value>* out_value) {
  ToJSValue(isolate, const_cast<const ScriptValue<Promise<T>>*>(promise_holder),
            out_value);
}

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

#endif  // COBALT_SCRIPT_V8C_NATIVE_PROMISE_H_
