// 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_FUNCTION_H_
#define LIB_ASYNC_PATTERNS_CPP_FUNCTION_H_

#include <lib/async_patterns/cpp/internal/tag.h>
#include <lib/async_patterns/cpp/internal/task_queue.h>
#include <lib/async_patterns/cpp/pending_call.h>
#include <lib/async_patterns/cpp/sendable.h>
#include <lib/fit/function.h>
#include <zircon/assert.h>

namespace async_patterns {

template <typename Owner>
class Receiver;

template <typename F>
class Function;

// An asynchronous |Function| that will always execute on the async dispatcher
// associated with a |Receiver|. Invoking this function translates to posting a
// task to the destination dispatcher. It will not block the caller.
//
// The receiver may not necessarily receive the function call. The call will be
// a no-op if:
// - The |Receiver| object goes out of scope.
// - The async dispatcher of the |Receiver| shuts down.
//
// A function can be invoked many times, and distributed to many senders. It is
// akin to a multi-producer, single-consumer, uni-directional channel. Calls
// posted to the same |Receiver| will be processed in the order they are made,
// regardless which |Function|s and |Callback|s they are made from.
template <typename ReturnType, typename... Args>
class Function<ReturnType(Args...)> {
 public:
  // Schedules the call to be asynchronously run on the receiver's
  // dispatcher.
  //
  // See |async_patterns::BindForSending| for detailed requirements on |args|.
  //
  // This operator returns a pending call. 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 |async_patterns::PendingCall| for details.
  //
  // Example:
  //
  //     async_patterns::Function<int(std::string)> parse = ...;
  //
  //     // Ignore the returned integer.
  //     parse(std::string("abc"));
  //
  //     // Get a promise that will resolve when the function is asynchronously
  //     // executed on the receiver's async dispatcher.
  //     fpromise::promise<int> promise = parse(std::string("abc")).promise();
  //
  auto operator()(Args... args) {
    ZX_DEBUG_ASSERT(task_queue_handle_.has_value());
    return PendingCall{
        BindForSending([f = function_](auto&&... args) { return (*f)(std::move(args)...); },
                       std::forward<Args>(args)...),
        internal::SubmitWithTaskQueueHandle{task_queue_handle_}, internal::Tag<ReturnType>{}};
  }

  // Returns a functor that performs the same actions as this |Function|, but returns
  // void, instead of potentially a promise object. This is useful when converting the
  // |Function| into a |fit::function<void(ReturnType)|.
  auto ignore_result() && {
    return [function = std::move(*this)](Args... args) mutable {
      function(std::forward<Args>(args)...);
    };
  }

 private:
  // The worst case scenario is a pointer-to-member (2 words) and a weak pointer (2 words).
  // We can improve this further using custom weak pointer types if necessary.
  using FunctionType = fit::inline_function<ReturnType(Args...), sizeof(void*) * 4>;

  template <typename Owner>
  friend class ::async_patterns::Receiver;

  explicit Function(internal::TaskQueueHandle handle, FunctionType callback)
      : task_queue_handle_(std::move(handle)),
        function_(std::make_shared<FunctionType>(std::move(callback))) {}

  internal::TaskQueueHandle task_queue_handle_;

  // |function_| is reference counted because both |Function| and the remote
  // task queue need to access it. |Function| uses it to schedule more calls.
  // The task queue uses it to invoke user supplied logic.
  std::shared_ptr<FunctionType> function_;
};

}  // namespace async_patterns

#endif  // LIB_ASYNC_PATTERNS_CPP_FUNCTION_H_
