// 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
