/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * 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 INCLUDE_PERFETTO_EXT_BASE_THREADING_FUTURE_H_
#define INCLUDE_PERFETTO_EXT_BASE_THREADING_FUTURE_H_

#include <memory>
#include <type_traits>

#include "perfetto/ext/base/status_or.h"
#include "perfetto/ext/base/threading/future_combinators.h"
#include "perfetto/ext/base/threading/poll.h"

namespace perfetto {
namespace base {

// Creates a Future<T> from P, a subclass of FuturePollable<T>.
//
// T generally is a primitive (e.g. int, string, double) or structs of
// primitives but any can also be any moveable type.
//
// This function follows the same pattern of std::make_unique, std::make_shared
// etc.
template <typename P, typename... Args, typename T = typename P::PollT>
Future<T> MakeFuture(Args... args) {
  return Future<T>(
      std::unique_ptr<FuturePollable<T>>(new P(std::forward<Args>(args)...)));
}

// A value of type T which is computed asynchronously.
//
// The result of long running compute/IO operations may not be available
// immediately. This class acts as a representation of the value which will be
// produced at some point in the future. Callers can then be notified of the
// result once it's available to be processed.
//
// This class takes heavy inspiration from the implementation of Futures in
// Rust. Specifically, this implementation is:
//  - pull-based/lazy: Futures do nothing until "polled" i.e. driven to
//    completion by a base::TaskRunner. The implementation of this is provided
//    by base::TaskRunnerPoller.
//  - backpressured: because futures are "polled", the result is only
//    requested when it can be processed on the base::TaskRunner thread.
//  - cancellable: by just destroying the future the computation can be
//    cancelled. Note, that the implementation of the source future still needs
//    to propogate cancellation across thread/socket/pipe boundary.
//
// Implementation note:
// An important point to note is that Future<T> is a final class. Implementation
// of Future<T>::Poll happens through an indirection layer by implementing the
// FuturePollable<T> interface. This allows for the
// unique_ptr<FuturePollable<T>> to be hidden, making callsites nicer while
// also allowing useful "helper" functions like |ContinueWith| to live on the
// class rather than as free functions.
template <typename T>
class Future final {
 public:
  using PollT = T;

  // Creates a Future from a |FuturePollable<T>|. Prefer using |MakeFuture|
  // instead of this function.
  explicit Future(std::unique_ptr<FuturePollable<T>> pollable)
      : pollable_(std::move(pollable)) {}

  // Intentionally implicit to allow for ergonomic definition of functions
  // returning Future<T> for any T.
  Future(T item) : pollable_(new ImmediateImpl<T>(std::move(item))) {}

  // Intentionally implicit to allow for egonomic definition of functions
  // returning Future<StatusOr<T>> by simply returning ErrStatus.
  // The enable_if is necessary because this definition is the same as the above
  // constructor in cases where T = base::Status.
  template <typename U = T,
            typename = std::enable_if_t<!std::is_same_v<Status, U>>>
  Future(Status status) : Future(T(std::move(status))) {}

  // Intentionally implicit to allow for egonomic definition of functions
  // returning Future<StatusOr<T>> by simply returning T.
  template <typename U = T, typename = typename U::value_type>
  Future(typename U::value_type val) : Future(T(std::move(val))) {}

  // Operator used to chain operations on Futures. The result T produced by
  // |this| is passed to |fn| which itself returns a Future<U>. The return value
  // of this function is a Future<U> which encapsulates both the operation done
  // by |this| as well as by the Future<U> returned by |fn|.
  //
  // Usage:
  // ```
  // Future<int> MySpecialFutureFn();
  // Future<std::string> IntToStringInBackground(int);
  //
  // MySpecialFutureFn().ContinueWith([](int x) -> Future<std::string> {
  //   return IntToStringInBackground(x);
  // });
  // ```
  template <typename Function /* Future<U>(T) */,
            typename U = FutureReturn<Function, T>>
  Future<U> ContinueWith(Function fn) && {
    return MakeFuture<ContinueWithImpl<Function, T>>(std::move(*this),
                                                     std::move(fn));
  }

  // Checks if the computation backing this Future<T> has finished.
  //
  // Returns a FuturePollResult<T> which is a essentially a
  // variant<PendingPollResult, T>. If PendingPollResult is returned, |ctx| will
  // be used to register interest in the various fds which are "blocking" this
  // future from finishing. If T is returned, Poll *must not* be called again.
  FuturePollResult<T> Poll(PollContext* ctx) { return pollable_->Poll(ctx); }

 private:
  // TOOD(lalitm): if performance becomes a problem, this can be changed to
  // something more efficient e.g. either storage in a stack allocated buffer
  // or with bump-pointer allocation. In the current usage this is not a
  // performance bottleneck and so this is not important enough to invest time
  // into fixing.
  std::unique_ptr<FuturePollable<T>> pollable_;
};

// Alias to shorten type defintions for Future<Status> which is common in
// the codebase.
using StatusFuture = Future<Status>;

// Alias to shorten type defintions for Future<StatusOr<T>> which is common
// in the codebase.
template <typename T>
using StatusOrFuture = Future<StatusOr<T>>;

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_THREADING_FUTURE_H_
