// Copyright 2017 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 SRC_LIB_CALLBACK_SCOPED_TASK_RUNNER_H_
#define SRC_LIB_CALLBACK_SCOPED_TASK_RUNNER_H_

#include <lib/async/default.h>
#include <lib/async/dispatcher.h>
#include <lib/fit/function.h>
#include <lib/fit/function_traits.h>
#include <lib/zx/time.h>

#include <memory>

#include "src/lib/fxl/macros.h"

namespace callback {

class TaskController {
 public:
  template <class T>
  struct Tag {};

  TaskController();
  virtual ~TaskController();

  // Indicates that further calls to |RunTask| should no-op. Implementations may
  // choose to block until running or outstanding tasks have completed.
  //
  // This method must be idempotent.
  virtual void ShutDown() = 0;
  // Runs a task immediately, or no-ops if this controller has shut down.
  virtual void RunTask(fit::closure task) = 0;

 private:
  FXL_DISALLOW_COPY_ASSIGN_AND_MOVE(TaskController);
};

// A basic task controller that does not synchronize shutdown with task
// execution. Client code is responsible for ensuring that any tasks that may be
// running when the runner is destroyed do not rely on invalid state, typically
// by ensuring that |ShutDown| occurs on the dispatch thread.
class SimpleTaskController : public TaskController {
 public:
  // For ergonomics, this could be a constexpr static Tag<SimpleTaskController>
  // but C++ would then allocate a (small) nonzero size for it. If we only use
  // it inline, it can be optimized out.
  // http://www.open-std.org/jtc1/sc22/open/n2356/class.html, s9p3
  using Type = Tag<SimpleTaskController>;

 private:
  // |TaskController|
  // This implementation does not block, and should be called on the dispatch
  // thread.
  void ShutDown() override;
  // |TaskController|
  void RunTask(fit::closure task) override;

  // This could easily be a std::atomic_bool, but since this implementation is
  // not synchronized, in correct code I don't think there's a case where this
  // makes a difference.
  //
  // A common idiom is to use |fxl::WeakPtr| for this kind of guard. However,
  // that is not thread-safe as |fxl::WeakPtr| contains non-atomic flag
  // twiddling, and |fxl::WeakPtr::InvalidateWeakPtrs| allows new valid pointers
  // to be created after it is called so it cannot be used as a |ShutDown|
  // method. Despite being unsynchronized, |SimpleTaskController| lets the
  // caller |ShutDown| on the dispatch thread.
  bool alive_ = true;
};

// An object that wraps the posting logic of an |async_t|, but that is
// not copyable and will generally not run any task after being deleted, though
// edge case handling may differ between |Controller| implementations.
//
// This class is mostly thread-safe, though it must not go out of scope while
// any of its methods are being called, and handling of edge cases varies
// depending on the controller implementation. Notably, the default |Controller|
// is not synchronized, so |ShutDown| should occur on the dispatch thread (after
// which destruction may happen on any thread).
//
// Typically, this class should appear towards the end of the fields of an
// owning class so that it goes out of scope before any state that tasks may
// depend on.
//
// This class may be used without a dispatcher, but the common use case is to
// manage FIDL calls.
class ScopedTaskRunner {
 public:
  explicit ScopedTaskRunner(async_dispatcher_t* dispatcher = async_get_default_dispatcher());

  template <class Controller>
  explicit ScopedTaskRunner(typename TaskController::Tag<Controller> controller_type,
                            async_dispatcher_t* dispatcher = async_get_default_dispatcher())
      : dispatcher_(dispatcher), controller_(std::make_shared<Controller>()) {}

  ScopedTaskRunner(const ScopedTaskRunner&) = delete;
  ScopedTaskRunner(ScopedTaskRunner&&);

  ~ScopedTaskRunner();

  ScopedTaskRunner& operator=(const ScopedTaskRunner&) = delete;
  ScopedTaskRunner& operator=(ScopedTaskRunner&&);

  async_dispatcher_t* dispatcher() const { return dispatcher_; }

  // Pre-emptively ends this ScopedTaskRunner's lifecycle. All subsequent tasks
  // will no-op. This method may block, depending on the |TaskController|
  // implementation. The default implementation does not block, so care should
  // be taken by callers that any tasks executing during shutdown do not depend
  // on state guarded by this instance, typically by calling this method from
  // the dispatch thread.
  //
  // This method is idempotent and will automatically be called when this class
  // goes out of scope.
  void ShutDown();

  // Shuts down the current controller and assigns a new |SimpleTaskController|.
  void Reset();

  // Shuts down the current controller and assigns a new one of the specified type.
  template <class Controller>
  void Reset(typename TaskController::Tag<Controller> controller_type) {
    ShutDown();
    controller_ = std::make_shared<Controller>();
  }

  // Posts a task to run as soon as possible on the dispatcher after the current
  // dispatch cycle.
  void PostTask(fit::closure task);

  // Posts a task to run as soon as possible after the specified |target_time|.
  void PostTaskForTime(fit::closure task, zx::time target_time);

  // Posts a task to run as soon as possible after the specified |delay|.
  void PostDelayedTask(fit::closure task, zx::duration delay);

  // Convenience function to post a repeating periodic task. If |invoke_now| is
  // true, the task is run as soon as possible on the dispatcher after the
  // current dispatch cycle as well as periodically. Otherwise, the first
  // invocation of the task will be as soon as possible after the specified
  // |interval|.
  void PostPeriodicTask(fit::closure task, zx::duration interval, bool invoke_now = true);

  // Scopes a task to the current task runner without scheduling it. This means
  // that the given function will be called when the returned function is called
  // if and only if this task runner has not been deleted or shut down.
  // Synchronization of the guard depends on the |TaskController|
  // implementation; the default implementation is unsynchronized.
  template <class Task, class... Args>
  auto MakeScoped(Task task, fit::parameter_pack<Args...>) {
    return [controller = controller_, task = std::move(task)](Args... args) mutable {
      // This differs from |callback::MakeScoped| in that |controller| is aware
      // of the task from start to finish, as opposed to |callback::MakeScoped|
      // which only consults |witness| when the task begins.
      return controller->RunTask(
          [task = std::move(task), &args...]() mutable { task(std::forward<Args>(args)...); });
    };
  }

  template <class Task>
  auto MakeScoped(Task task) {
    return MakeScoped(std::move(task), typename fit::function_traits<Task>::args{});
  }

 private:
  async_dispatcher_t* dispatcher_;
  std::shared_ptr<TaskController> controller_;
};

}  // namespace callback

#endif  // SRC_LIB_CALLBACK_SCOPED_TASK_RUNNER_H_
