// 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 "base/logging.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/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>. Does not implement the Resolve
// function, since that needs to be specialized for Promise<T>.
template <typename T>
class NativePromise : public ScopedPersistent<v8::Value>, public Promise<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)
      : isolate_(isolate), ScopedPersistent(isolate, resolver) {
    DCHECK(resolver->IsPromise());
  }

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

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

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

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

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

    v8::Local<v8::Promise::Resolver> promise_resolver = this->resolver();
    v8::Local<v8::Value> error_result = CreateErrorObject(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(!this->IsEmpty());
    DCHECK(State() == PromiseState::kPending);
    EntryScope entry_scope(isolate_);
    v8::Local<v8::Context> context = isolate_->GetCurrentContext();

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

  PromiseState State() const override {
    DCHECK(!this->IsEmpty());
    EntryScope entry_scope(isolate_);

    v8::Promise::PromiseState v8_promise_state = this->promise()->State();
    switch (v8_promise_state) {
      case v8::Promise::kPending:
        return PromiseState::kPending;
      case v8::Promise::kFulfilled:
        return PromiseState::kFulfilled;
      case v8::Promise::kRejected:
        return PromiseState::kRejected;
    }
    NOTREACHED();
    return PromiseState::kRejected;
  }

  v8::Local<v8::Promise> promise() const {
    DCHECK(!this->IsEmpty());
    return resolver()->GetPromise();
  }

 private:
  v8::Isolate* isolate_;

  v8::Local<v8::Promise::Resolver> resolver() const {
    DCHECK(!this->IsEmpty());
    return this->Get().Get(isolate_).template As<v8::Promise::Resolver>();
  }
};

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_
