// Copyright 2017 the V8 project 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 V8_LIBPLATFORM_DEFAULT_FOREGROUND_TASK_RUNNER_H_
#define V8_LIBPLATFORM_DEFAULT_FOREGROUND_TASK_RUNNER_H_

#include <memory>
#include <queue>

#include "include/libplatform/libplatform.h"
#include "include/v8-platform.h"
#include "src/base/platform/condition-variable.h"
#include "src/base/platform/mutex.h"

namespace v8 {
namespace platform {

class V8_PLATFORM_EXPORT DefaultForegroundTaskRunner
    : public NON_EXPORTED_BASE(TaskRunner) {
 public:
  using TimeFunction = double (*)();
  class RunTaskScope {
   public:
    explicit RunTaskScope(
        std::shared_ptr<DefaultForegroundTaskRunner> task_runner);
    ~RunTaskScope();
    RunTaskScope(const RunTaskScope&) = delete;
    RunTaskScope& operator=(const RunTaskScope&) = delete;

   private:
    std::shared_ptr<DefaultForegroundTaskRunner> task_runner_;
  };

  DefaultForegroundTaskRunner(IdleTaskSupport idle_task_support,
                              TimeFunction time_function);

  void Terminate();

  std::unique_ptr<Task> PopTaskFromQueue(MessageLoopBehavior wait_for_work);

  std::unique_ptr<IdleTask> PopTaskFromIdleQueue();

  double MonotonicallyIncreasingTime();

  // v8::TaskRunner implementation.
  void PostTask(std::unique_ptr<Task> task) override;
  void PostDelayedTask(std::unique_ptr<Task> task,
                       double delay_in_seconds) override;

  void PostIdleTask(std::unique_ptr<IdleTask> task) override;
  bool IdleTasksEnabled() override;

  void PostNonNestableTask(std::unique_ptr<Task> task) override;
  void PostNonNestableDelayedTask(std::unique_ptr<Task> task,
                                  double delay_in_seconds) override;
  bool NonNestableTasksEnabled() const override;

 private:
  enum Nestability { kNestable, kNonNestable };

  void WaitForTaskLocked(const base::MutexGuard&);

  // The same as PostTask or PostNonNestableTask, but the lock is already held
  // by the caller. The {guard} parameter should make sure that the caller is
  // holding the lock.
  void PostTaskLocked(std::unique_ptr<Task> task, Nestability nestability,
                      const base::MutexGuard&);

  // The same as PostDelayedTask or PostNonNestableDelayedTask, but the lock is
  // already held by the caller. The {guard} parameter should make sure that the
  // caller is holding the lock.
  void PostDelayedTaskLocked(std::unique_ptr<Task> task,
                             double delay_in_seconds, Nestability nestability,
                             const base::MutexGuard&);

  // A caller of this function has to hold {lock_}. The {guard} parameter should
  // make sure that the caller is holding the lock.
  std::unique_ptr<Task> PopTaskFromDelayedQueueLocked(const base::MutexGuard&,
                                                      Nestability* nestability);

  // A non-nestable task is poppable only if the task runner is not nested,
  // i.e. if a task is not being run from within a task. A nestable task is
  // always poppable.
  bool HasPoppableTaskInQueue() const;

  // Move delayed tasks that hit their deadline to the main queue.
  void MoveExpiredDelayedTasks(const base::MutexGuard& guard);

  bool terminated_ = false;
  base::Mutex lock_;
  base::ConditionVariable event_loop_control_;
  int nesting_depth_ = 0;

  using TaskQueueEntry = std::pair<Nestability, std::unique_ptr<Task>>;
  std::deque<TaskQueueEntry> task_queue_;

  IdleTaskSupport idle_task_support_;
  std::queue<std::unique_ptr<IdleTask>> idle_task_queue_;

  // Some helper constructs for the {delayed_task_queue_}.
  struct DelayedEntry {
    double timeout_time;
    Nestability nestability;
    std::unique_ptr<Task> task;
  };

  // Define a comparison operator for the delayed_task_queue_ to make sure
  // that the unique_ptr in the DelayedEntry is not accessed in the priority
  // queue. This is necessary because we have to reset the unique_ptr when we
  // remove a DelayedEntry from the priority queue.
  struct DelayedEntryCompare {
    bool operator()(const DelayedEntry& left, const DelayedEntry& right) const {
      return left.timeout_time > right.timeout_time;
    }
  };
  std::priority_queue<DelayedEntry, std::vector<DelayedEntry>,
                      DelayedEntryCompare>
      delayed_task_queue_;

  TimeFunction time_function_;
};

}  // namespace platform
}  // namespace v8
#endif  // V8_LIBPLATFORM_DEFAULT_FOREGROUND_TASK_RUNNER_H_
