// Copyright 2023 The Fuchsia 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 LIB_ASYNC_PATTERNS_CPP_DISPATCHER_BOUND_H_
#define LIB_ASYNC_PATTERNS_CPP_DISPATCHER_BOUND_H_

#include <lib/async/dispatcher.h>
#include <lib/async_patterns/cpp/internal/dispatcher_bound_storage.h>
#include <lib/async_patterns/cpp/pending_call.h>
#include <lib/fit/function.h>
#include <lib/fit/function_traits.h>
#include <lib/stdcompat/functional.h>
#include <zircon/assert.h>

#include <cstdlib>
#include <utility>

namespace async_patterns {

// |DispatcherBound<T>| does not allow sending raw pointers to the wrapped
// object. However, it is common for an async object to obtain its associated
// |async_dispatcher_t*|. Often that can be accomplished with
// |async_get_default_dispatcher|, but in case where that's not feasible, one
// may specify the |async_patterns::PassDispatcher| constant in place of an
// |async_dispatcher_t*|, at the argument location where the wrapped async
// object desires a dispatcher, and |DispatcherBound| will automatically supply
// the correct dispatcher that the async object is associated with.
constexpr auto PassDispatcher = internal::PassDispatcherT{};

// |DispatcherBound<T>| enables an owner object living on some arbitrary thread,
// to construct, call methods on, and destroy an object of type |T| that must be
// used from a particular [synchronized async dispatcher][synchronized-dispatcher].
//
// Thread-unsafe asynchronous types should be used from synchronized dispatchers
// (e.g. a single-threaded async loop). Because the dispatcher may be running
// code to manipulate such objects, one should not use the same objects from
// other unrelated threads and cause data races.
//
// However, it may not always be possible for an entire tree of objects to
// live on the same async dispatcher, due to design or legacy constraints.
// |DispatcherBound| helps one divide classes along dispatcher boundaries.
//
// An example:
//
//     // |Background| always lives on a background dispatcher, provided
//     // at construction time.
//     class Background {
//      public:
//       explicit Background() {
//         // Perform some asynchronous work. The work is canceled if
//         // |Background| is destroyed.
//         task_.Post(async_get_default_dispatcher());
//       }
//
//      private:
//       void DoSomething();
//
//       // |task_| manages an async task that borrows the containing
//       // |Background| object and is not thread safe. It must be destroyed
//       // on the dispatcher to ensure that task cancellation is not racy.
//       async::TaskClosureMethod<Background, &Background::DoSomething> task_{this};
//     };
//
//     class Owner {
//      public:
//       // Asynchronously constructs a |Background| object on its dispatcher.
//       // Code in |Owner| and code in |Background| may run concurrently.
//       //
//       // The dispatcher will not be attached to the current thread, but will
//       // be attached to the loop thread. This way, the |Background| object
//       // can obtain a dispatcher from its constructor using
//       // |async_get_default_dispatcher|.
//       explicit Owner() :
//           background_loop_(&kAsyncLoopConfigNoAttachToCurrentThread),
//           background_{background_loop_.dispatcher(), std::in_place} {}
//
//      private:
//       // The async loop which will manage |Background| objects.
//       // This will always be paired with a |DispatcherBound| object.
//       async::Loop background_loop_;
//
//       // The |DispatcherBound| which manages |Background| on its loop.
//       // During destruction, |background_| will schedule the asynchronous
//       // destruction of the wrapped |Background| object on the dispatcher.
//       async_patterns::DispatcherBound<Background> background_;
//     };
//
// |DispatcherBound| itself is thread-compatible.
//
// ## Safety of sending arguments
//
// When constructing |T| and calling member functions of |T|, it is possible to
// pass additional arguments if the constructor or member function requires it.
// The argument will be forwarded from the caller's thread into a heap data
// structure, and later moved into the thread which would run the dispatcher
// task asynchronously. Each argument must be safe to send to a different
// thread. See |async_patterns::BindForSending| for the detailed requirements.
//
// [synchronized-dispatcher]:
// https://fuchsia.dev/fuchsia-src/development/languages/c-cpp/thread-safe-async#synchronized-dispatcher
template <typename T>
class DispatcherBound {
 public:
  // Asynchronously constructs |T| on a task posted to |dispatcher|.
  //
  // Arguments after |std::in_place| are sent to the constructor of |T|.
  // See |async_patterns::BindForSending| for detailed requirements on |args|.
  //
  // If you'd like to pass a |dispatcher| to |T| as a constructor argument,
  // see |async_patterns::PassDispatcher|.
  //
  // If the dispatcher is shutdown, |T| will be synchronously constructed.
  template <typename... Args>
  explicit DispatcherBound(async_dispatcher_t* dispatcher, std::in_place_t, Args&&... args)
      : dispatcher_(dispatcher) {
    storage_.Construct<T, T>(dispatcher, std::forward<Args>(args)...);
  }

  // Constructs a |DispatcherBound| that does not hold an instance of |T|.
  //
  // One may later construct |T| using |emplace| on the |dispatcher|.
  explicit DispatcherBound(async_dispatcher_t* dispatcher) : dispatcher_(dispatcher) {}

  // Asynchronously constructs |T| on a task posted to the dispatcher.
  //
  // If this object already holds an instance of |T|, that older instance will
  // be asynchronously destroyed on the dispatcher.
  //
  // If |T2| is specified, it must be same as |T| or a subclass. Then an instance
  // of |T2| will be constructed. This can be useful for mocking: |T| may be some
  // interface, and when constructing the object, either a fake (in unit tests)
  // or a real concrete type (in production) will be specified.
  //
  // If you'd like to pass a |dispatcher| to |T| as a constructor argument,
  // see |async_patterns::PassDispatcher|.
  //
  // See |async_patterns::BindForSending| for detailed requirements on |args|.
  template <typename T2 = T, typename... Args>
  void emplace(Args&&... args) {
    static_assert(std::is_base_of_v<T, T2>, "|T| must be a base class of |T2|.");
    reset();
    storage_.Construct<T, T2>(dispatcher_, std::forward<Args>(args)...);
  }

  // Asynchronously calls |member|, a pointer to member function of |T|, using
  // the provided |args|.
  //
  // |AsyncCall| returns a |PendingCall| object that lets you asynchronously
  // monitor the result. You may either:
  //
  // - Make a fire-and-forget call, by discarding the returned object, or
  // - Get a promise carrying the return value of the function by calling
  //   `promise()` on the object, yielding a |fpromise::promise<ReturnType>|, or
  // - Call `Then()` on the object and pass a |Callback<void(ReturnType)>|.
  //
  // See |PendingCall| for details.
  //
  // In particular, if |member| returns void, you could attach promises/callbacks
  // that take void to asynchronously get notified when |member| has finished execution.
  //
  // Example:
  //
  //     class Owner {
  //      public:
  //       Owner(async_dispatcher_t* owner_dispatcher) : receiver_{this, owner_dispatcher} {
  //         background_.emplace();
  //         // Tell |background_| to |DoSomething|, then send back the return
  //         // value to |Owner| using |receiver_|.
  //         background_
  //             .AsyncCall(&Background::DoSomething)
  //             .Then(receiver_.Once(&Owner::DoneSomething));
  //       }
  //
  //       void DoneSomething(Result result) {
  //         // |Background::DoSomething| has completed with |result|...
  //       }
  //
  //      private:
  //       async::Loop background_loop_;
  //       async_patterns::DispatcherBound<Background> background_{background_loop_.dispatcher()};
  //       async_patterns::Receiver<Owner> receiver_;
  //     };
  //
  // See |async_patterns::BindForSending| for detailed requirements on |args|.
  //
  // If |Background::DoSomething| is an overloaded member function, you may
  // disambiguate it by spelling out its signature:
  //
  //     background_.AsyncCall<void(Result)>(&Background::DoSomething);
  //
  // The task will be synchronously called if the dispatcher is shutdown.
  template <typename Member, typename... Args>
  auto AsyncCall(Member T::*member, Args&&... args) {
    ZX_ASSERT(has_value());
    constexpr bool kIsInvocable = std::is_invocable_v<Member, Args...>;
    static_assert(kIsInvocable,
                  "|Member| must be callable with the provided |Args|. "
                  "Check that you specified each argument correctly to the |member| function.");
    if constexpr (kIsInvocable) {
      CheckArgs(typename fit::callable_traits<Member>::args{});
      return UnsafeAsyncCallImpl(member, std::forward<Args>(args)...);
    }
  }

  // Typically, asynchronous classes would contain internal self-pointers that
  // make moving dangerous, so we disable moves here for now.
  DispatcherBound(DispatcherBound&&) noexcept = delete;
  DispatcherBound& operator=(DispatcherBound&&) noexcept = delete;

  DispatcherBound(const DispatcherBound&) noexcept = delete;
  DispatcherBound& operator=(const DispatcherBound&) noexcept = delete;

  // If |has_value|, asynchronously destroys the managed |T| on a task
  // posted to the dispatcher.
  //
  // If the dispatcher is shutdown, |T| will be synchronously destroyed.
  ~DispatcherBound() { reset(); }

  // If |has_value|, asynchronously destroys the managed |T| on a task
  // posted to the dispatcher.
  //
  // If the dispatcher is shutdown, |T| will be synchronously destroyed.
  void reset() {
    if (!has_value()) {
      return;
    }
    storage_.Destruct(dispatcher_);
  }

  // Returns if this object holds an instance of |T|.
  bool has_value() const { return storage_.has_value(); }

 protected:
  // Calls an arbitrary |callable| asynchronously on the |dispatcher_|.
  template <template <typename, typename, typename> typename Builder = PendingCall,
            typename Callable, typename... Args>
  auto UnsafeAsyncCallImpl(Callable&& callable, Args&&... args) {
    using Result = std::invoke_result_t<Callable, T*, Args...>;
    return storage_.AsyncCall<Builder, Result, T>(dispatcher_, std::forward<Callable>(callable),
                                                  std::forward<Args>(args)...);
  }

  template <typename... Args>
  constexpr void CheckArgs(fit::parameter_pack<Args...>) {
    internal::CheckArguments<Args...>::Check();
  }

 private:
  async_dispatcher_t* dispatcher_;
  internal::DispatcherBoundStorage storage_;
};

// Constructs a |DispatcherBound<T>| that holds an instance of |T| by sending
// the |args| to the constructor of |T| run from a |dispatcher| task.
//
// See |DispatcherBound| constructor for details.
template <typename T, typename... Args>
DispatcherBound<T> MakeDispatcherBound(async_dispatcher_t* dispatcher, Args&&... args) {
  return DispatcherBound<T>{dispatcher, std::in_place, std::forward<Args>(args)...};
}

}  // namespace async_patterns

#endif  // LIB_ASYNC_PATTERNS_CPP_DISPATCHER_BOUND_H_
