// Copyright 2015 The Chromium OS 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 <brillo/message_loops/fake_message_loop.h>

#include <base/logging.h>
#include <brillo/location_logging.h>

namespace brillo {

FakeMessageLoop::FakeMessageLoop(base::SimpleTestClock* clock)
    : test_clock_(clock) {}

MessageLoop::TaskId FakeMessageLoop::PostDelayedTask(
    const base::Location& from_here,
    base::OnceClosure task,
    base::TimeDelta delay) {
  // If no SimpleTestClock was provided, we use the last time we fired a
  // callback. In this way, tasks scheduled from a Closure will have the right
  // time.
  if (test_clock_)
    current_time_ = test_clock_->Now();
  MessageLoop::TaskId current_id = ++last_id_;
  // FakeMessageLoop is limited to only 2^64 tasks. That should be enough.
  CHECK(current_id);
  tasks_.emplace(current_id, ScheduledTask{from_here, std::move(task)});
  fire_order_.push(std::make_pair(current_time_ + delay, current_id));
  VLOG_LOC(from_here, 1) << "Scheduling delayed task_id " << current_id
                         << " to run at " << current_time_ + delay << " (in "
                         << delay << ").";
  return current_id;
}

bool FakeMessageLoop::CancelTask(TaskId task_id) {
  if (task_id == MessageLoop::kTaskIdNull)
    return false;
  bool ret = tasks_.erase(task_id) > 0;
  VLOG_IF(1, ret) << "Removing task_id " << task_id;
  return ret;
}

bool FakeMessageLoop::RunOnce(bool may_block) {
  if (test_clock_)
    current_time_ = test_clock_->Now();
  // Try to fire time-based callbacks afterwards.
  while (!fire_order_.empty() &&
         (may_block || fire_order_.top().first <= current_time_)) {
    const auto task_ref = fire_order_.top();
    fire_order_.pop();
    // We need to skip tasks in the priority_queue not in the |tasks_| map.
    // This is normal if the task was canceled, as there is no efficient way
    // to remove a task from the priority_queue.
    const auto scheduled_task_ref = tasks_.find(task_ref.second);
    if (scheduled_task_ref == tasks_.end())
      continue;
    // Advance the clock to the task firing time, if needed.
    if (current_time_ < task_ref.first) {
      current_time_ = task_ref.first;
      if (test_clock_)
        test_clock_->SetNow(current_time_);
    }
    // Move the Closure out of the map before delete it. We need to delete the
    // entry from the map before we call the callback, since calling CancelTask
    // for the task you are running now should fail and return false.
    base::OnceClosure callback = std::move(scheduled_task_ref->second.callback);
    VLOG_LOC(scheduled_task_ref->second.location, 1)
        << "Running task_id " << task_ref.second << " at time " << current_time_
        << " from this location.";
    tasks_.erase(scheduled_task_ref);

    std::move(callback).Run();
    return true;
  }
  return false;
}

bool FakeMessageLoop::PendingTasks() {
  for (const auto& task : tasks_) {
    VLOG_LOC(task.second.location, 1)
        << "Pending task_id " << task.first << " scheduled from here.";
  }
  return !tasks_.empty();
}

}  // namespace brillo
