// Copyright 2023 The Pigweed Authors
//
// 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
//
//     https://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.
#pragma once

#include <mutex>
#include <optional>

#include "pw_assert/assert.h"
#include "pw_async2/poll.h"
#include "pw_chrono/system_clock.h"
#include "pw_sync/interrupt_spin_lock.h"
#include "pw_sync/lock_annotations.h"
#include "pw_toolchain/no_destructor.h"

namespace pw::async2 {

/// A lock guarding the ``Task`` queue and ``Waker`` lists.
///
/// This is an ``InterruptSpinLock`` in order to allow posting work from ISR
/// contexts.
///
/// This lock is global rather than per-dispatcher in order to allow ``Task``
/// and ``Waker`` to take out the lock without dereferencing their
/// ``Dispatcher*`` fields, which are themselves guarded by the lock in order
/// to allow the ``Dispatcher`` to ``Deregister`` itself upon destruction.
inline pw::sync::InterruptSpinLock& dispatcher_lock() {
  static NoDestructor<pw::sync::InterruptSpinLock> lock;
  return *lock;
}

class DispatcherBase;
class Waker;
class WaitReason;

// Forward-declare ``Dispatcher``.
// This concrete type must be provided by a backend.
class Dispatcher;

/// Context for an asynchronous ``Task``.
///
/// This object contains resources needed for scheduling asynchronous work,
/// such as the current ``Dispatcher`` and the ``Waker`` for the current task.
///
/// ``Context`` s are most often created by ``Dispatcher`` s, which pass them
/// into ``Task::Pend``.
class Context {
 public:
  /// Creates a new ``Context`` containing the currently-running ``Dispatcher``
  /// and a ``Waker`` for the current ``Task``.
  Context(Dispatcher& dispatcher, Waker& waker)
      : dispatcher_(&dispatcher), waker_(&waker) {}

  /// The ``Dispatcher`` on which the current ``Task`` is executing.
  ///
  /// This can be used for spawning new tasks using
  /// ``dispatcher().Post(task);``.
  Dispatcher& dispatcher() { return *dispatcher_; }

  /// Queues the current ``Task::Pend`` to run again in the future, possibly
  /// after other work is performed.
  ///
  /// This may be used by ``Task`` implementations that wish to provide
  /// additional fairness by yielding to the dispatch loop rather than perform
  /// too much work in a single iteration.
  ///
  /// This is semantically equivalent to calling ``GetWaker(...).Wake()``
  void ReEnqueue();

  /// Returns a ``Waker`` which, when awoken, will cause the current task to be
  /// ``Pend``'d by its dispatcher.
  Waker GetWaker(WaitReason reason);

 private:
  Dispatcher* dispatcher_;
  Waker* waker_;
};

/// A task which may complete one or more asynchronous operations.
///
/// The ``Task`` interface is commonly implemented by users wishing to schedule
/// work on an  asynchronous ``Dispatcher``. To do this, users may subclass
/// ``Task``, providing an implementation of the ``DoPend`` method which
/// advances the state of the ``Task`` as far as possible before yielding back
/// to the ``Dispatcher``.
///
/// This process works similarly to cooperatively-scheduled green threads or
/// coroutines, with a ``Task`` representing a single logical "thread" of
/// execution. Unlike some green thread or coroutine implementations, ``Task``
/// does not imply a separately-allocated stack: ``Task`` state is most
/// commonly stored in fields of the ``Task`` subclass.
///
/// Once defined by a user, ``Task`` s may be run by passing them to a
/// ``Dispatcher`` via ``Dispatcher::Post``. The ``Dispatcher`` will then
/// ``Pend`` the ``Task`` every time that the ``Task`` indicates it is able
/// to make progress.
///
/// Note that ``Task`` objects *must not* be destroyed while they are actively
/// being ``Pend``'d by a ``Dispatcher``. The best way to ensure this is to
/// create ``Task`` objects that continue to live until they receive a
/// ``DoDestroy`` call or which outlive their associated ``Dispatcher``.
class Task {
  friend class Waker;
  friend class DispatcherBase;
  template <typename T>
  friend class DispatcherImpl;

 public:
  Task() = default;
  Task(Task&) = delete;
  Task(Task&&) = delete;
  Task& operator=(Task&) = delete;
  Task& operator=(Task&&) = delete;
  virtual ~Task() {
    // Note: the task must not be registered with a ``Dispatcher` upon
    // destruction. This happens automatically upon ``Task`` completion or upon
    // ``Dispatcher`` destruction.
    //
    // This is necessary to ensure that neither the ``Dispatcher`` nor
    // ``Waker`` reference the ``Task`` object after destruction.
    //
    // Note that the ``~Task`` destructor cannot perform this deregistration,
    // as there is no guarantee that (1) the task is not being actively polled
    // and (2) by the time the ``~Task`` destructor is reached, the subclass
    // destructor has already run, invalidating the subclass state that may be
    // read by the ``Pend`` implementation.
  }

  // A public interface for ``DoPend``.
  //
  // ``DoPend`` is normally invoked by a ``Dispatcher`` after a ``Task`` has
  // been ``Post`` ed.
  //
  // This wrapper should only be called by ``Task`` s delegating to other
  // ``Task`` s.  For example, a ``class MainTask`` might have separate fields
  // for  ``TaskA` and ``TaskB``, and could invoke ``Pend`` on these types
  // within its own ``DoPend`` implementation.
  Poll<> Pend(Context& cx) { return DoPend(cx); }

  // A public interface for ``DoDestroy``.
  //
  // ``DoDestroy`` is normally invoked by a ``Dispatcher`` after a ``Post`` ed
  // ``Task`` has completed.
  //
  // This should only be called by ``Task`` s delegating to other ``Task`` s.
  void Destroy() { DoDestroy(); }

 private:
  /// Attempts to advance this ``Task`` to completion.
  ///
  /// This method should not perform synchronous waiting, as doing so may block
  /// the main ``Dispatcher`` loop and prevent other ``Task`` s from
  /// progressing. Because of this, ``Task`` s should not invoke blocking
  /// ``Dispatcher`` methods such as ``RunUntilComplete``.
  ///
  /// ``Task`` s should also avoid invoking ``RunUntilStalled` on their own
  /// ``Dispatcher``.
  ///
  /// Returns ``Ready`` if complete, or ``Pending`` if the ``Task`` was not yet
  /// able to complete.
  ///
  /// If ``Pending`` is returned, the ``Task`` must ensure it is woken up when
  /// it is able to make progress. To do this, ``Task::Pend`` must arrange for
  /// ``Waker::Wake`` to be called, either by storing a copy of the ``Waker``
  /// away to be awoken by another system (such as an interrupt handler).
  virtual Poll<> DoPend(Context&) = 0;

  /// Performs any necessary cleanup of ``Task`` memory after completion.
  ///
  /// This may include calls to ``std::destroy_at(this)``, and may involve
  /// deallocating the memory for this ``Task`` itself.
  ///
  /// Tasks implementations which wish to be reused may skip self-destruction
  /// here.
  virtual void DoDestroy() {}

  // Unlinks all ``Waker`` objects associated with this ``Task.``
  void RemoveAllWakersLocked() PW_EXCLUSIVE_LOCKS_REQUIRED(dispatcher_lock());

  // Adds a ``Waker`` to the linked list of ``Waker`` s tracked by this
  // ``Task``.
  void AddWakerLocked(Waker&) PW_EXCLUSIVE_LOCKS_REQUIRED(dispatcher_lock());

  // Removes a ``Waker`` from the linked list of ``Waker`` s tracked by this
  // ``Task``
  //
  // Precondition: the provided waker *must* be in the list of ``Waker`` s
  // tracked by this ``Task``.
  void RemoveWakerLocked(Waker&) PW_EXCLUSIVE_LOCKS_REQUIRED(dispatcher_lock());

  enum class State {
    kUnposted,
    kRunning,
    kWoken,
    kSleeping,
  };
  // The current state of the task.
  State state_ PW_GUARDED_BY(dispatcher_lock()) = State::kUnposted;

  // A pointer to the dispatcher this task is associated with.
  //
  // This will be non-null when `state_` is anything other than `kUnposted`.
  //
  // This value must be cleared by the dispatcher upon destruction in order to
  // prevent null access.
  DispatcherBase* dispatcher_ PW_GUARDED_BY(dispatcher_lock()) = nullptr;

  // Pointers for whatever linked-list this ``Task`` is in.
  // These are controlled by the ``Dispatcher``.
  Task* prev_ PW_GUARDED_BY(dispatcher_lock()) = nullptr;
  Task* next_ PW_GUARDED_BY(dispatcher_lock()) = nullptr;

  // A pointer to the first element of the linked list of ``Waker`` s that may
  // awaken this ``Task``.
  Waker* wakers_ PW_GUARDED_BY(dispatcher_lock()) = nullptr;
};

/// An identifier indicating the kind of event a ``Waker`` is waiting for.
///
/// This identifier may be stored for debugging purposes.
class WaitReason {
 public:
  /// Indicates that the wait is happen for an unspecified reason.
  static WaitReason Unspecified() { return WaitReason(); }

 private:
  WaitReason() {}
};

/// An object which can respond to asynchronous events by queueing work to
/// be done in response, such as placing a ``Task`` on a ``Dispatcher`` loop.
///
/// ``Waker`` s are often held by I/O objects, custom concurrency primitives,
/// or interrupt handlers. Once the thing the ``Task`` was waiting for is
/// available, ``Wake`` should be called so that the ``Task`` is alerted and
/// may process the event.
///
/// ``Waker`` s may be held for any lifetime, and will be automatically
/// nullified when the underlying ``Dispatcher`` or ``Task`` is deleted.
///
/// ``Waker`` s are most commonly created by ``Dispatcher`` s, which pass them
/// into ``Task::Pend`` via its ``Context`` argument.
class Waker {
  friend class Task;
  friend class DispatcherBase;
  template <typename T>
  friend class DispatcherImpl;

 public:
  Waker() = default;
  Waker(Waker&& other) noexcept PW_LOCKS_EXCLUDED(dispatcher_lock());

  /// Replace this ``Waker`` with another.
  ///
  /// This operation is guaranteed to be thread-safe.
  Waker& operator=(Waker&& other) noexcept PW_LOCKS_EXCLUDED(dispatcher_lock());

  ~Waker() noexcept { RemoveFromTaskWakerList(); }

  /// Wakes up the ``Waker``'s creator, alerting it that an asynchronous
  /// event has occurred that may allow it to make progress.
  ///
  /// ``Wake`` operates on an rvalue reference (``&&``) in order to indicate
  /// that the event that was waited on has been complete. This makes it
  /// possible to track the outstanding events that may cause a ``Task`` to
  /// wake up and make progress.
  ///
  /// This operation is guaranteed to be thread-safe.
  void Wake() && PW_LOCKS_EXCLUDED(dispatcher_lock());

  /// Creates a second ``Waker`` from this ``Waker``.
  ///
  /// ``Clone`` is made explicit in order to allow for easier tracking of
  /// the different ``Waker``s that may wake up a ``Task``.
  ///
  /// The ``WaitReason`` argument can be used to provide information about
  /// what event the ``Waker`` is waiting on. This can be useful for
  /// debugging purposes.
  ///
  /// This operation is guaranteed to be thread-safe.
  Waker Clone(WaitReason reason) & PW_LOCKS_EXCLUDED(dispatcher_lock());

  /// Returns whether this ``Waker`` is empty.
  ///
  /// Empty wakers are those that perform no action upon wake. These may be
  /// created either via the default no-argument constructor or by
  /// calling ``Clear`` or ``std::move`` on a ``Waker``, after which the
  /// moved-from ``Waker`` will be empty.
  ///
  /// This operation is guaranteed to be thread-safe.
  [[nodiscard]] bool IsEmpty() const PW_LOCKS_EXCLUDED(dispatcher_lock());

  /// Clears this ``Waker``.
  ///
  /// After this call, ``Wake`` will no longer perform any action, and
  /// ``IsEmpty`` will return ``true``.
  ///
  /// This operation is guaranteed to be thread-safe.
  void Clear() PW_LOCKS_EXCLUDED(dispatcher_lock()) {
    RemoveFromTaskWakerList();
  }

 private:
  Waker(Task& task) PW_LOCKS_EXCLUDED(dispatcher_lock()) : task_(&task) {
    InsertIntoTaskWakerList();
  }

  void InsertIntoTaskWakerList();
  void InsertIntoTaskWakerListLocked()
      PW_EXCLUSIVE_LOCKS_REQUIRED(dispatcher_lock());
  void RemoveFromTaskWakerList();
  void RemoveFromTaskWakerListLocked()
      PW_EXCLUSIVE_LOCKS_REQUIRED(dispatcher_lock());

  // The ``Task`` to poll when awoken.
  Task* task_ PW_GUARDED_BY(dispatcher_lock()) = nullptr;

  // The next ``Waker`` that may awaken this ``Task``.
  // This list is controlled by the corresponding ``Task``.
  Waker* next_ PW_GUARDED_BY(dispatcher_lock()) = nullptr;
};

/// A base class used by ``Dispatcher`` implementations.
///
/// Note that only one ``Dispatcher`` implementation should exist per
/// toolchain. However, a common base class is used in order to share
/// behavior and standardize the interface of these ``Dispatcher`` s,
/// and to prevent build system cycles due to ``Task`` needing to refer
/// to the ``Dispatcher`` class.
class DispatcherBase {
 public:
  DispatcherBase() = default;
  DispatcherBase(DispatcherBase&) = delete;
  DispatcherBase(DispatcherBase&&) = delete;
  DispatcherBase& operator=(DispatcherBase&) = delete;
  DispatcherBase& operator=(DispatcherBase&&) = delete;
  virtual ~DispatcherBase() {}

 protected:
  /// Check that a task is posted on this ``Dispatcher``.
  bool HasPostedTask(Task& task)
      PW_EXCLUSIVE_LOCKS_REQUIRED(dispatcher_lock()) {
    return task.dispatcher_ == this;
  }

  /// Removes references to this ``DispatcherBase`` from all linked ``Task`` s
  /// and ``Waker`` s.
  ///
  /// This must be called by ``Dispatcher`` implementations in their
  /// destructors. It is not called by the ``DispatcherBase`` destructor, as
  /// doing so would allow the ``Dispatcher`` to be referenced between the
  /// calls to ``~Dispatcher`` and ``~DispatcherBase``.
  void Deregister() PW_LOCKS_EXCLUDED(dispatcher_lock());

 private:
  friend class Task;
  friend class Waker;
  template <typename Impl>
  friend class DispatcherImpl;

  /// Sends a wakeup signal to this ``Dispatcher``.
  ///
  /// This method's implementation should ensure that the ``Dispatcher`` comes
  /// back from sleep and begins invoking ``RunOneTask`` again.
  ///
  /// Note: the ``dispatcher_lock()`` may or may not be held here, so it must
  /// not be acquired by ``DoWake``, nor may ``DoWake`` assume that it has been
  /// acquired.
  virtual void DoWake() = 0;

  static void UnpostTaskList(Task*)
      PW_EXCLUSIVE_LOCKS_REQUIRED(dispatcher_lock());
  static void RemoveTaskFromList(Task&)
      PW_EXCLUSIVE_LOCKS_REQUIRED(dispatcher_lock());
  void RemoveWokenTaskLocked(Task&)
      PW_EXCLUSIVE_LOCKS_REQUIRED(dispatcher_lock());
  void RemoveSleepingTaskLocked(Task&)
      PW_EXCLUSIVE_LOCKS_REQUIRED(dispatcher_lock());

  // For use by ``WakeTask`` and ``DispatcherImpl::Post``.
  void AddTaskToWokenList(Task&) PW_EXCLUSIVE_LOCKS_REQUIRED(dispatcher_lock());

  // For use by ``RunOneTask``.
  void AddTaskToSleepingList(Task&)
      PW_EXCLUSIVE_LOCKS_REQUIRED(dispatcher_lock());

  // For use by ``Waker``.
  void WakeTask(Task&) PW_EXCLUSIVE_LOCKS_REQUIRED(dispatcher_lock());

  // For use by ``RunOneTask``.
  Task* PopWokenTask() PW_EXCLUSIVE_LOCKS_REQUIRED(dispatcher_lock());

  Task* first_woken_ PW_GUARDED_BY(dispatcher_lock()) = nullptr;
  Task* last_woken_ PW_GUARDED_BY(dispatcher_lock()) = nullptr;
  // Note: the sleeping list's order is not significant.
  Task* sleeping_ PW_GUARDED_BY(dispatcher_lock()) = nullptr;
  bool wants_wake_ PW_GUARDED_BY(dispatcher_lock()) = false;
};

/// Information about whether and when to sleep until as returned by
/// ``DispatcherBase::AttemptRequestWake``.
///
/// This should only be used by ``Dispatcher`` implementations.
class [[nodiscard]] SleepInfo {
  template <typename T>
  friend class DispatcherImpl;

 public:
  bool should_sleep() const { return should_sleep_; }

 private:
  SleepInfo(bool should_sleep) : should_sleep_(should_sleep) {}

  static SleepInfo DontSleep() { return SleepInfo(false); }

  static SleepInfo Indefinitely() { return SleepInfo(true); }

  bool should_sleep_;
};

/// Information about the result of a call to ``RunOneTask``.
///
/// This should only be used by ``Dispatcher`` implementations.
class [[nodiscard]] RunOneTaskResult {
  template <typename T>
  friend class DispatcherImpl;

 public:
  RunOneTaskResult(bool completed_all_tasks,
                   bool completed_main_task,
                   bool ran_a_task)
      : completed_all_tasks_(completed_all_tasks),
        completed_main_task_(completed_main_task),
        ran_a_task_(ran_a_task) {}
  bool completed_all_tasks() const { return completed_all_tasks_; }
  bool completed_main_task() const { return completed_main_task_; }
  bool ran_a_task() const { return ran_a_task_; }

 private:
  bool completed_all_tasks_;
  bool completed_main_task_;
  bool ran_a_task_;
};

/// A CRTP base class used by ``Dispatcher`` implementations.
///
/// This is used to provide a common public interface for all ``Dispatcher``
/// implementations.
///
/// Note that only one ``Dispatcher`` implementation should exist per
/// toolchain. However, a common base class is used in order to share
/// behavior and standardize the interface of these ``Dispatcher`` s,
/// and to prevent build system cycles due to ``Task`` needing to refer
/// to the ``Dispatcher`` class.
template <typename Impl>
class DispatcherImpl : public DispatcherBase {
 public:
  /// Tells the ``Dispatcher`` to run ``Task`` to completion.
  /// This method does not block.
  ///
  /// After ``Post`` is called, ``Task::Pend`` will be invoked once.
  /// If ``Task::Pend`` does not complete, the ``Dispatcher`` will wait
  /// until the ``Task`` is "awoken", at which point it will call ``Pend``
  /// again until the ``Task`` completes.
  void Post(Task& task) PW_LOCKS_EXCLUDED(dispatcher_lock()) {
    bool wake_dispatcher = false;
    {
      std::lock_guard lock(dispatcher_lock());
      PW_DASSERT(task.state_ == Task::State::kUnposted);
      PW_DASSERT(task.dispatcher_ == nullptr);
      task.state_ = Task::State::kWoken;
      task.dispatcher_ = this;
      AddTaskToWokenList(task);
      if (wants_wake_) {
        wake_dispatcher = true;
        wants_wake_ = false;
      }
    }
    // Note: unlike in ``WakeTask``, here we know that the ``Dispatcher`` will
    // not be destroyed out from under our feet because we're in a method being
    // called on the ``Dispatcher`` by a user.
    if (wake_dispatcher) {
      DoWake();
    }
  }

  /// Runs tasks until none are able to make immediate progress.
  Poll<> RunUntilStalled() PW_LOCKS_EXCLUDED(dispatcher_lock()) {
    return self().DoRunUntilStalled(nullptr);
  }

  /// Runs tasks until none are able to make immediate progress, or until
  /// ``task`` completes.
  ///
  /// Returns whether ``task`` completed.
  Poll<> RunUntilStalled(Task& task) PW_LOCKS_EXCLUDED(dispatcher_lock()) {
    return self().DoRunUntilStalled(&task);
  }

  /// Runs until all tasks complete.
  void RunToCompletion() PW_LOCKS_EXCLUDED(dispatcher_lock()) {
    self().DoRunToCompletion(nullptr);
  }

  /// Runs until ``task`` completes.
  void RunToCompletion(Task& task) PW_LOCKS_EXCLUDED(dispatcher_lock()) {
    self().DoRunToCompletion(&task);
  }

 protected:
  /// Indicates that this ``Dispatcher`` is about to go to sleep and
  /// requests that it be awoken when more work is available in the future.
  ///
  /// Dispatchers must invoke this method before sleeping in order to ensure
  /// that they receive a ``DoWake`` call when there is more work to do.
  ///
  /// The returned ``SleepInfo`` will describe whether and for how long the
  /// ``Dispatcher`` implementation should go to sleep. Notably it will return
  /// that the ``Dispatcher`` should not sleep if there is still more work to
  /// be done.
  SleepInfo AttemptRequestWake() PW_LOCKS_EXCLUDED(dispatcher_lock()) {
    std::lock_guard lock(dispatcher_lock());
    // Don't allow sleeping if there are already tasks waiting to be run.
    if (first_woken_ != nullptr) {
      return SleepInfo::DontSleep();
    }
    /// Indicate that the ``Dispatcher`` is sleeping and will need a ``DoWake``
    /// call once more work can be done.
    wants_wake_ = true;
    // Once timers are added, this should check them.
    return SleepInfo::Indefinitely();
  }

  /// Attempts to run a single task, returning whether any tasks were
  /// run, and whether `task_to_look_for` was run.
  [[nodiscard]] RunOneTaskResult RunOneTask(Task* task_to_look_for)
      PW_LOCKS_EXCLUDED(dispatcher_lock()) {
    Task* task;
    {
      std::lock_guard lock(dispatcher_lock());
      task = PopWokenTask();
      if (task == nullptr) {
        bool all_complete = first_woken_ == nullptr && sleeping_ == nullptr;
        return RunOneTaskResult(
            /*completed_all_tasks=*/all_complete,
            /*completed_main_task=*/false,
            /*ran_a_task=*/false);
      }
      task->state_ = Task::State::kRunning;
    }

    bool complete;
    {
      Waker waker(*task);
      Context context(self(), waker);
      complete = task->Pend(context).IsReady();
    }
    if (complete) {
      bool all_complete;
      {
        std::lock_guard lock(dispatcher_lock());
        switch (task->state_) {
          case Task::State::kUnposted:
          case Task::State::kSleeping:
            PW_DASSERT(false);
            PW_UNREACHABLE;
          case Task::State::kRunning:
            break;
          case Task::State::kWoken:
            RemoveWokenTaskLocked(*task);
            break;
        }
        task->state_ = Task::State::kUnposted;
        task->dispatcher_ = nullptr;
        task->RemoveAllWakersLocked();
        all_complete = first_woken_ == nullptr && sleeping_ == nullptr;
      }
      task->DoDestroy();
      return RunOneTaskResult(
          /*completed_all_tasks=*/all_complete,
          /*completed_main_task=*/task == task_to_look_for,
          /*ran_a_task=*/true);
    } else {
      std::lock_guard lock(dispatcher_lock());
      if (task->state_ == Task::State::kRunning) {
        task->state_ = Task::State::kSleeping;
        AddTaskToSleepingList(*task);
      }
      return RunOneTaskResult(
          /*completed_all_tasks=*/false,
          /*completed_main_task=*/false,
          /*ran_a_task=*/true);
    }
  }

 private:
  /// Returns ``this`` as a base class reference.
  Impl& self() { return *static_cast<Impl*>(this); }
};

}  // namespace pw::async2
