// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_TASK_PROMISE_PROMISE_H_
#define BASE_TASK_PROMISE_PROMISE_H_

#include "base/task/post_task.h"
#include "base/task/promise/helpers.h"
#include "base/task/promise/no_op_promise_executor.h"
#include "base/task/promise/promise_result.h"
#include "base/task/promise/then_and_catch_executor.h"
#include "base/threading/sequenced_task_runner_handle.h"

namespace base {

// Inspired by ES6 promises, Promise<> is a PostTask based callback system for
// asynchronous operations. An operation can resolve (succeed) with a value and
// optionally reject (fail) with a different result. Interested parties can be
// notified using ThenOn() and CatchOn() which schedule callbacks to run as
// appropriate on the specified task runner or task traits. If a promise is
// settled when a ThenOn() / CatchOn() / FinallyOn() statement is added, the
// callback will be posted immediately, otherwise it has to wait.
//
// Promise<> is copyable, moveable and thread safe. Under the hood
// internal::AbstractPromise is refcounted so retaining multiple Promises<> will
// prevent that part of the promise graph from being released.
template <typename ResolveType, typename RejectType = NoReject>
class Promise {
 public:
  Promise() : abstract_promise_(nullptr) {}

  explicit Promise(
      scoped_refptr<internal::AbstractPromise> abstract_promise) noexcept
      : abstract_promise_(std::move(abstract_promise)) {}

  // Constructs an unresolved promise for use by a ManualPromiseResolver<> and
  // TaskRunner::PostPromise.
  Promise(scoped_refptr<TaskRunner> task_runner,
          const Location& location,
          RejectPolicy reject_policy)
      : abstract_promise_(MakeRefCounted<internal::AbstractPromise>(
            std::move(task_runner),
            location,
            nullptr,
            reject_policy,
            internal::AbstractPromise::ConstructWith<
                internal::DependentList::ConstructUnresolved,
                internal::NoOpPromiseExecutor>(),
            /* can_resolve */ !std::is_same<ResolveType, NoResolve>::value,
            /* can_reject */ !std::is_same<RejectType, NoReject>::value)) {}

  NOINLINE ~Promise() = default;

  operator bool() const { return !!abstract_promise_; }

  bool IsCancelledForTesting() const {
    DCHECK(abstract_promise_);
    return abstract_promise_->IsCanceled();
  }

  // A task to execute |on_reject| is posted on |task_runner| as soon as this
  // promise (or an uncaught ancestor) is rejected. A Promise<> for the return
  // value of |on_reject| is returned.
  //
  // The following callback return types have special meanings:
  // 1. PromiseResult<Resolve, Reject> lets the callback resolve, reject or
  //    curry a Promise<Resolve, Reject>
  // 2. Promise<Resolve, Reject> where the result is a curried promise.
  //
  // If a promise has multiple Catches they will be run in order of creation.
  template <typename RejectCb>
  NOINLINE auto CatchOn(scoped_refptr<TaskRunner> task_runner,
                        const Location& from_here,
                        RejectCb&& on_reject) noexcept {
    DCHECK(abstract_promise_);

    // Extract properties from the |on_reject| callback.
    using RejectCallbackTraits = internal::CallbackTraits<RejectCb>;
    using RejectCallbackArgT = typename RejectCallbackTraits::ArgType;

    // Compute the resolve and reject types of the returned Promise.
    using ReturnedPromiseTraits =
        internal::PromiseCombiner<ResolveType,
                                  NoReject,  // We've caught the reject case.
                                  typename RejectCallbackTraits::ResolveType,
                                  typename RejectCallbackTraits::RejectType>;
    using ReturnedPromiseResolveT = typename ReturnedPromiseTraits::ResolveType;
    using ReturnedPromiseRejectT = typename ReturnedPromiseTraits::RejectType;

    static_assert(!std::is_same<NoReject, RejectType>::value,
                  "Can't catch a NoReject promise.");

    // Check we wouldn't need to return Promise<Variant<...>, ...>
    static_assert(ReturnedPromiseTraits::valid,
                  "Ambiguous promise resolve type");
    static_assert(
        internal::IsValidPromiseArg<RejectType, RejectCallbackArgT>::value ||
            std::is_void<RejectCallbackArgT>::value,
        "|on_reject| callback must accept Promise::RejectType or void.");

    return Promise<ReturnedPromiseResolveT, ReturnedPromiseRejectT>(
        MakeRefCounted<internal::AbstractPromise>(
            std::move(task_runner), from_here,
            std::make_unique<internal::AbstractPromise::AdjacencyList>(
                abstract_promise_),
            RejectPolicy::kMustCatchRejection,
            internal::AbstractPromise::ConstructWith<
                internal::DependentList::ConstructUnresolved,
                internal::ThenAndCatchExecutor<
                    OnceClosure,  // Never called.
                    OnceCallback<typename RejectCallbackTraits::SignatureType>,
                    internal::NoCallback, RejectType,
                    Resolved<ReturnedPromiseResolveT>,
                    Rejected<ReturnedPromiseRejectT>>>(),
            OnceClosure(),
            static_cast<
                OnceCallback<typename RejectCallbackTraits::SignatureType>>(
                std::forward<RejectCb>(on_reject))));
  }

  template <typename RejectCb>
  auto CatchOn(const TaskTraits& traits,
               const Location& from_here,
               RejectCb&& on_reject) noexcept {
    return CatchOn(CreateTaskRunnerWithTraits(traits), from_here,
                   std::forward<RejectCb>(on_reject));
  }

  template <typename RejectCb>
  auto CatchOnCurrent(const Location& from_here,
                      RejectCb&& on_reject) noexcept {
    return CatchOn(SequencedTaskRunnerHandle::Get(), from_here,
                   std::forward<RejectCb>(on_reject));
  }

  // A task to execute |on_resolve| is posted on |task_runner| as soon as this
  // promise (or an unhandled ancestor) is resolved. A Promise<> for the return
  // value of |on_resolve| is returned.
  //
  // The following callback return types have special meanings:
  // 1. PromiseResult<Resolve, Reject> lets the callback resolve, reject or
  //    curry a Promise<Resolve, Reject>
  // 2. Promise<Resolve, Reject> where the result is a curried promise.
  //
  // If a promise has multiple Thens they will be run in order of creation.
  template <typename ResolveCb>
  NOINLINE auto ThenOn(scoped_refptr<TaskRunner> task_runner,
                       const Location& from_here,
                       ResolveCb&& on_resolve) noexcept {
    DCHECK(abstract_promise_);

    // Extract properties from the |on_resolve| callback.
    using ResolveCallbackTraits =
        internal::CallbackTraits<std::decay_t<ResolveCb>>;
    using ResolveCallbackArgT = typename ResolveCallbackTraits::ArgType;

    // Compute the resolve and reject types of the returned Promise.
    using ReturnedPromiseTraits =
        internal::PromiseCombiner<NoResolve,  // We've caught the resolve case.
                                  RejectType,
                                  typename ResolveCallbackTraits::ResolveType,
                                  typename ResolveCallbackTraits::RejectType>;
    using ReturnedPromiseResolveT = typename ReturnedPromiseTraits::ResolveType;
    using ReturnedPromiseRejectT = typename ReturnedPromiseTraits::RejectType;

    // Check we wouldn't need to return Promise<..., Variant<...>>
    static_assert(ReturnedPromiseTraits::valid,
                  "Ambiguous promise reject type");

    static_assert(
        internal::IsValidPromiseArg<ResolveType, ResolveCallbackArgT>::value ||
            std::is_void<ResolveCallbackArgT>::value,
        "|on_resolve| callback must accept Promise::ResolveType or void.");

    return Promise<ReturnedPromiseResolveT, ReturnedPromiseRejectT>(
        MakeRefCounted<internal::AbstractPromise>(
            std::move(task_runner), from_here,
            std::make_unique<internal::AbstractPromise::AdjacencyList>(
                abstract_promise_),
            RejectPolicy::kMustCatchRejection,
            internal::AbstractPromise::ConstructWith<
                internal::DependentList::ConstructUnresolved,
                internal::ThenAndCatchExecutor<
                    OnceCallback<typename ResolveCallbackTraits::SignatureType>,
                    OnceClosure, ResolveType, internal::NoCallback,
                    Resolved<ReturnedPromiseResolveT>,
                    Rejected<ReturnedPromiseRejectT>>>(),
            std::forward<ResolveCb>(on_resolve), OnceClosure()));
  }

  template <typename ResolveCb>
  auto ThenOn(const TaskTraits& traits,
              const Location& from_here,
              ResolveCb&& on_resolve) noexcept {
    return ThenOn(CreateTaskRunnerWithTraits(traits), from_here,
                  std::forward<ResolveCb>(on_resolve));
  }

  template <typename ResolveCb>
  auto ThenOnCurrent(const Location& from_here,
                     ResolveCb&& on_resolve) noexcept {
    return ThenOn(SequencedTaskRunnerHandle::Get(), from_here,
                  std::forward<ResolveCb>(on_resolve));
  }

  // A task to execute |on_reject| is posted on |task_runner| as soon as this
  // promise (or an uncaught ancestor) is rejected. Likewise a task to execute
  // |on_resolve| is posted on |task_runner| as soon as this promise (or an
  // unhandled ancestor) is resolved. A Promise<> for the return value of
  // |on_resolve| or |on_reject| is returned.
  //
  // The following callback return types have special meanings:
  // 1. PromiseResult<Resolve, Reject> lets the callback resolve, reject or
  //    curry a Promise<Resolve, Reject>
  // 2. Promise<Resolve, Reject> where the result is a curried promise.
  //
  // If a promise has multiple Catches/ Thens, they will be run in order of
  // creation.
  //
  // Note if either |on_resolve| or |on_reject| are canceled (due to weak
  // pointer invalidation), then the other must be canceled at the same time as
  // well. This restriction only applies to this form of ThenOn/ThenOnCurrent.
  template <typename ResolveCb, typename RejectCb>
  NOINLINE auto ThenOn(scoped_refptr<TaskRunner> task_runner,
                       const Location& from_here,
                       ResolveCb&& on_resolve,
                       RejectCb&& on_reject) noexcept {
    DCHECK(abstract_promise_);

    // Extract properties from the |on_resolve| and |on_reject| callbacks.
    using ResolveCallbackTraits = internal::CallbackTraits<ResolveCb>;
    using RejectCallbackTraits = internal::CallbackTraits<RejectCb>;
    using ResolveCallbackArgT = typename ResolveCallbackTraits::ArgType;
    using RejectCallbackArgT = typename RejectCallbackTraits::ArgType;

    // Compute the resolve and reject types of the returned Promise.
    using ReturnedPromiseTraits =
        internal::PromiseCombiner<typename ResolveCallbackTraits::ResolveType,
                                  typename ResolveCallbackTraits::RejectType,
                                  typename RejectCallbackTraits::ResolveType,
                                  typename RejectCallbackTraits::RejectType>;
    using ReturnedPromiseResolveT = typename ReturnedPromiseTraits::ResolveType;
    using ReturnedPromiseRejectT = typename ReturnedPromiseTraits::RejectType;

    static_assert(!std::is_same<NoReject, RejectType>::value,
                  "Can't catch a NoReject promise.");

    static_assert(ReturnedPromiseTraits::valid,
                  "|on_resolve| callback and |on_resolve| callback must return "
                  "compatible types.");

    static_assert(
        internal::IsValidPromiseArg<ResolveType, ResolveCallbackArgT>::value ||
            std::is_void<ResolveCallbackArgT>::value,
        "|on_resolve| callback must accept Promise::ResolveType or void.");

    static_assert(
        internal::IsValidPromiseArg<RejectType, RejectCallbackArgT>::value ||
            std::is_void<RejectCallbackArgT>::value,
        "|on_reject| callback must accept Promise::RejectType or void.");

    return Promise<ReturnedPromiseResolveT, ReturnedPromiseRejectT>(
        MakeRefCounted<internal::AbstractPromise>(
            std::move(task_runner), from_here,
            std::make_unique<internal::AbstractPromise::AdjacencyList>(
                abstract_promise_),
            RejectPolicy::kMustCatchRejection,
            internal::AbstractPromise::ConstructWith<
                internal::DependentList::ConstructUnresolved,
                internal::ThenAndCatchExecutor<
                    OnceCallback<typename ResolveCallbackTraits::SignatureType>,
                    OnceCallback<typename RejectCallbackTraits::SignatureType>,
                    ResolveType, RejectType, Resolved<ReturnedPromiseResolveT>,
                    Rejected<ReturnedPromiseRejectT>>>(),
            static_cast<
                OnceCallback<typename ResolveCallbackTraits::SignatureType>>(
                std::forward<ResolveCb>(on_resolve)),
            static_cast<
                OnceCallback<typename RejectCallbackTraits::SignatureType>>(
                std::forward<RejectCb>(on_reject))));
  }

  template <typename ResolveCb, typename RejectCb>
  auto ThenOn(const TaskTraits& traits,
              const Location& from_here,
              ResolveCb&& on_resolve,
              RejectCb&& on_reject) noexcept {
    return ThenOn(CreateTaskRunnerWithTraits(traits), from_here,
                  std::forward<ResolveCb>(on_resolve),
                  std::forward<RejectCb>(on_reject));
  }

  template <typename ResolveCb, typename RejectCb>
  auto ThenOnCurrent(const Location& from_here,
                     ResolveCb&& on_resolve,
                     RejectCb&& on_reject) noexcept {
    return ThenOn(SequencedTaskRunnerHandle::Get(), from_here,
                  std::forward<ResolveCb>(on_resolve),
                  std::forward<RejectCb>(on_reject));
  }

  template <typename... Args>
  NOINLINE static Promise<ResolveType, RejectType> CreateResolved(
      const Location& from_here,
      Args&&... args) noexcept {
    scoped_refptr<internal::AbstractPromise> promise(
        MakeRefCounted<internal::AbstractPromise>(
            nullptr, from_here, nullptr, RejectPolicy::kMustCatchRejection,
            internal::AbstractPromise::ConstructWith<
                internal::DependentList::ConstructResolved,
                internal::NoOpPromiseExecutor>(),
            /* can_resolve */ true,
            /* can_reject */ false));
    promise->emplace(Resolved<ResolveType>{std::forward<Args>(args)...});
    return Promise<ResolveType, RejectType>(std::move(promise));
  }

  template <typename... Args>
  NOINLINE static Promise<ResolveType, RejectType> CreateRejected(
      const Location& from_here,
      Args&&... args) noexcept {
    scoped_refptr<internal::AbstractPromise> promise(
        MakeRefCounted<internal::AbstractPromise>(
            nullptr, from_here, nullptr, RejectPolicy::kMustCatchRejection,
            internal::AbstractPromise::ConstructWith<
                internal::DependentList::ConstructRejected,
                internal::NoOpPromiseExecutor>(),
            /* can_resolve */ false,
            /* can_reject */ true));
    promise->emplace(Rejected<RejectType>{std::forward<Args>(args)...});
    return Promise<ResolveType, RejectType>(std::move(promise));
  }

  using ResolveT = ResolveType;
  using RejectT = RejectType;

 private:
  template <typename A, typename B>
  friend class Promise;

  template <typename A, typename B>
  friend class PromiseResult;

  template <typename RejectStorage, typename ResultStorage>
  friend struct internal::EmplaceHelper;

  template <typename A, typename B>
  friend class ManualPromiseResolver;

  scoped_refptr<internal::AbstractPromise> abstract_promise_;
};

// Used for manually resolving and rejecting a Promise. This is for
// compatibility with old code and will eventually be removed.
template <typename ResolveType, typename RejectType = NoReject>
class ManualPromiseResolver {
 public:
  using ResolveHelper = std::conditional_t<
      std::is_void<ResolveType>::value,
      internal::PromiseCallbackHelper<void>,
      internal::PromiseCallbackHelper<ResolveType, ResolveType>>;

  using RejectHelper = std::conditional_t<
      std::is_void<RejectType>::value,
      internal::PromiseCallbackHelper<void>,
      internal::PromiseCallbackHelper<RejectType, RejectType>>;

  ManualPromiseResolver(
      const Location& from_here,
      RejectPolicy reject_policy = RejectPolicy::kMustCatchRejection)
      : promise_(SequencedTaskRunnerHandle::Get(), from_here, reject_policy) {}

  template <typename... Args>
  void Resolve(Args&&... arg) noexcept {
    DCHECK(!promise_.abstract_promise_->IsResolved());
    DCHECK(!promise_.abstract_promise_->IsRejected());
    static_assert(!std::is_same<NoResolve, ResolveType>::value,
                  "Can't resolve a NoResolve promise.");
    promise_.abstract_promise_->emplace(
        Resolved<ResolveType>{std::forward<Args>(arg)...});
    promise_.abstract_promise_->OnResolved();
  }

  template <typename... Args>
  void Reject(Args&&... arg) noexcept {
    DCHECK(!promise_.abstract_promise_->IsResolved());
    DCHECK(!promise_.abstract_promise_->IsRejected());
    static_assert(!std::is_same<NoReject, RejectType>::value,
                  "Can't reject a NoReject promise.");
    promise_.abstract_promise_->emplace(
        Rejected<RejectType>{std::forward<Args>(arg)...});
    promise_.abstract_promise_->OnRejected();
  }

  typename ResolveHelper::Callback GetResolveCallback() {
    return ResolveHelper::GetResolveCallback(promise_.abstract_promise_);
  }

  typename ResolveHelper::RepeatingCallback GetRepeatingResolveCallback() {
    return ResolveHelper::GetRepeatingResolveCallback(
        promise_.abstract_promise_);
  }

  typename RejectHelper::Callback GetRejectCallback() {
    static_assert(!std::is_same<NoReject, RejectType>::value,
                  "Can't reject a NoReject promise.");
    return RejectHelper::GetRejectCallback(promise_.abstract_promise_);
  }

  typename RejectHelper::RepeatingCallback GetRepeatingRejectCallback() {
    static_assert(!std::is_same<NoReject, RejectType>::value,
                  "Can't reject a NoReject promise.");
    return RejectHelper::GetRepeatingRejectCallback(promise_.abstract_promise_);
  }

  Promise<ResolveType, RejectType>& promise() { return promise_; }

 private:
  Promise<ResolveType, RejectType> promise_;
};

}  // namespace base

#endif  // BASE_TASK_PROMISE_PROMISE_H_
