// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/task/task_scheduler/delayed_task_manager.h"

#include <algorithm>

#include "base/bind.h"
#include "base/logging.h"
#include "base/task/post_task.h"
#include "base/task/task_scheduler/task.h"
#include "base/task_runner.h"

namespace base {
namespace internal {

DelayedTaskManager::DelayedTask::DelayedTask(Task task,
                                             PostTaskNowCallback callback)
    : task(std::move(task)), callback(std::move(callback)) {}

DelayedTaskManager::DelayedTask::DelayedTask(
    DelayedTaskManager::DelayedTask&& other) = default;

DelayedTaskManager::DelayedTask::~DelayedTask() = default;

DelayedTaskManager::DelayedTask& DelayedTaskManager::DelayedTask::operator=(
    DelayedTaskManager::DelayedTask&& other) = default;

bool DelayedTaskManager::DelayedTask::operator>(
    const DelayedTask& other) const {
  return task.delayed_run_time > other.task.delayed_run_time;
}

bool DelayedTaskManager::DelayedTask::IsScheduled() const {
  return scheduled_;
}
void DelayedTaskManager::DelayedTask::SetScheduled() {
  DCHECK(!scheduled_);
  scheduled_ = true;
}

DelayedTaskManager::DelayedTaskManager(
    std::unique_ptr<const TickClock> tick_clock)
    : process_ripe_tasks_closure_(
          BindRepeating(&DelayedTaskManager::ProcessRipeTasks,
                        Unretained(this))),
      tick_clock_(std::move(tick_clock)) {
  DCHECK(tick_clock_);
}

DelayedTaskManager::~DelayedTaskManager() = default;

void DelayedTaskManager::Start(
    scoped_refptr<TaskRunner> service_thread_task_runner) {
  DCHECK(service_thread_task_runner);

  TimeTicks process_ripe_tasks_time;
  {
    AutoSchedulerLock auto_lock(queue_lock_);
    DCHECK(!service_thread_task_runner_);
    service_thread_task_runner_ = std::move(service_thread_task_runner);
    process_ripe_tasks_time = GetTimeToScheduleProcessRipeTasksLockRequired();
  }
  ScheduleProcessRipeTasksOnServiceThread(process_ripe_tasks_time);
}

void DelayedTaskManager::AddDelayedTask(
    Task task,
    PostTaskNowCallback post_task_now_callback) {
  DCHECK(task.task);
  DCHECK(!task.delayed_run_time.is_null());

  // Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167
  // for details.
  CHECK(task.task);
  TimeTicks process_ripe_tasks_time;
  {
    AutoSchedulerLock auto_lock(queue_lock_);
    delayed_task_queue_.emplace(std::move(task),
                                std::move(post_task_now_callback));
    // Not started yet.
    if (service_thread_task_runner_ == nullptr)
      return;
    process_ripe_tasks_time = GetTimeToScheduleProcessRipeTasksLockRequired();
  }
  ScheduleProcessRipeTasksOnServiceThread(process_ripe_tasks_time);
}

void DelayedTaskManager::ProcessRipeTasks() {
  std::vector<DelayedTask> ripe_delayed_tasks;
  TimeTicks process_ripe_tasks_time;

  {
    AutoSchedulerLock auto_lock(queue_lock_);
    const TimeTicks now = tick_clock_->NowTicks();
    while (!delayed_task_queue_.empty() &&
           delayed_task_queue_.top().task.delayed_run_time <= now) {
      // The const_cast on top is okay since the DelayedTask is
      // transactionnaly being popped from |delayed_task_queue_| right after
      // and the move doesn't alter the sort order (a requirement for the
      // Windows STL's consistency debug-checks for
      // std::priority_queue::top()).
      ripe_delayed_tasks.push_back(
          std::move(const_cast<DelayedTask&>(delayed_task_queue_.top())));
      delayed_task_queue_.pop();
    }
    process_ripe_tasks_time = GetTimeToScheduleProcessRipeTasksLockRequired();
  }
  ScheduleProcessRipeTasksOnServiceThread(process_ripe_tasks_time);

  for (auto& delayed_task : ripe_delayed_tasks) {
    std::move(delayed_task.callback).Run(std::move(delayed_task.task));
  }
}

TimeTicks DelayedTaskManager::GetTimeToScheduleProcessRipeTasksLockRequired() {
  queue_lock_.AssertAcquired();
  if (delayed_task_queue_.empty())
    return TimeTicks::Max();
  // The const_cast on top is okay since |IsScheduled()| and |SetScheduled()|
  // don't alter the sort order (a requirement for the Windows STL's consistency
  // debug-checks for std::priority_queue::top())
  DelayedTask& ripest_delayed_task =
      const_cast<DelayedTask&>(delayed_task_queue_.top());
  if (ripest_delayed_task.IsScheduled())
    return TimeTicks::Max();
  ripest_delayed_task.SetScheduled();
  return ripest_delayed_task.task.delayed_run_time;
}

void DelayedTaskManager::ScheduleProcessRipeTasksOnServiceThread(
    TimeTicks next_delayed_task_run_time) {
  DCHECK(!next_delayed_task_run_time.is_null());
  if (next_delayed_task_run_time.is_max())
    return;
  const TimeTicks now = tick_clock_->NowTicks();
  TimeDelta delay = std::max(TimeDelta(), next_delayed_task_run_time - now);
  service_thread_task_runner_->PostDelayedTask(
      FROM_HERE, process_ripe_tasks_closure_, delay);
}

}  // namespace internal
}  // namespace base
