// Copyright 2014 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 "cc/test/ordered_simple_task_runner.h"

#include <stddef.h>
#include <stdint.h>

#include <limits>
#include <set>
#include <sstream>
#include <string>
#include <vector>

#include "base/auto_reset.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_number_conversions.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"

#define TRACE_TASK(function, task) \
  TRACE_EVENT_INSTANT1(            \
      "cc", function, TRACE_EVENT_SCOPE_THREAD, "task", task.AsValue());

#define TRACE_TASK_RUN(function, tag, task)

namespace cc {

// TestOrderablePendingTask implementation
TestOrderablePendingTask::TestOrderablePendingTask()
    : base::TestPendingTask(),
      task_id_(TestOrderablePendingTask::task_id_counter++) {
}

TestOrderablePendingTask::TestOrderablePendingTask(
    const tracked_objects::Location& location,
    const base::Closure& task,
    base::TimeTicks post_time,
    base::TimeDelta delay,
    TestNestability nestability)
    : base::TestPendingTask(location, task, post_time, delay, nestability),
      task_id_(TestOrderablePendingTask::task_id_counter++) {
}

size_t TestOrderablePendingTask::task_id_counter = 0;

TestOrderablePendingTask::~TestOrderablePendingTask() {
}

bool TestOrderablePendingTask::operator==(
    const TestOrderablePendingTask& other) const {
  return task_id_ == other.task_id_;
}

bool TestOrderablePendingTask::operator<(
    const TestOrderablePendingTask& other) const {
  if (*this == other)
    return false;

  if (GetTimeToRun() == other.GetTimeToRun()) {
    return task_id_ < other.task_id_;
  }
  return ShouldRunBefore(other);
}

scoped_refptr<base::trace_event::ConvertableToTraceFormat>
TestOrderablePendingTask::AsValue() const {
  scoped_refptr<base::trace_event::TracedValue> state =
      new base::trace_event::TracedValue();
  AsValueInto(state.get());
  return state;
}

void TestOrderablePendingTask::AsValueInto(
    base::trace_event::TracedValue* state) const {
  state->SetInteger("id", base::saturated_cast<int>(task_id_));
  state->SetInteger("run_at", GetTimeToRun().ToInternalValue());
  state->SetString("posted_from", location.ToString());
}

OrderedSimpleTaskRunner::OrderedSimpleTaskRunner(
    base::SimpleTestTickClock* now_src,
    bool advance_now)
    : advance_now_(advance_now),
      now_src_(now_src),
      max_tasks_(kAbsoluteMaxTasks),
      inside_run_tasks_until_(false) {
}

OrderedSimpleTaskRunner::~OrderedSimpleTaskRunner() {}

// static
base::TimeTicks OrderedSimpleTaskRunner::AbsoluteMaxNow() {
  return base::TimeTicks::FromInternalValue(
      std::numeric_limits<int64_t>::max());
}

// base::TestSimpleTaskRunner implementation
bool OrderedSimpleTaskRunner::PostDelayedTask(
    const tracked_objects::Location& from_here,
    const base::Closure& task,
    base::TimeDelta delay) {
  DCHECK(thread_checker_.CalledOnValidThread());
  TestOrderablePendingTask pt(from_here, task, now_src_->NowTicks(), delay,
                              base::TestPendingTask::NESTABLE);

  TRACE_TASK("OrderedSimpleTaskRunner::PostDelayedTask", pt);
  pending_tasks_.insert(pt);
  return true;
}

bool OrderedSimpleTaskRunner::PostNonNestableDelayedTask(
    const tracked_objects::Location& from_here,
    const base::Closure& task,
    base::TimeDelta delay) {
  DCHECK(thread_checker_.CalledOnValidThread());
  TestOrderablePendingTask pt(from_here, task, now_src_->NowTicks(), delay,
                              base::TestPendingTask::NON_NESTABLE);

  TRACE_TASK("OrderedSimpleTaskRunner::PostNonNestableDelayedTask", pt);
  pending_tasks_.insert(pt);
  return true;
}

bool OrderedSimpleTaskRunner::RunsTasksOnCurrentThread() const {
  DCHECK(thread_checker_.CalledOnValidThread());
  return true;
}

size_t OrderedSimpleTaskRunner::NumPendingTasks() const {
  return pending_tasks_.size();
}

bool OrderedSimpleTaskRunner::HasPendingTasks() const {
  return pending_tasks_.size() > 0;
}

base::TimeTicks OrderedSimpleTaskRunner::NextTaskTime() {
  if (pending_tasks_.size() <= 0) {
    return AbsoluteMaxNow();
  }

  return pending_tasks_.begin()->GetTimeToRun();
}

base::TimeDelta OrderedSimpleTaskRunner::DelayToNextTaskTime() {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (pending_tasks_.size() <= 0) {
    return AbsoluteMaxNow() - base::TimeTicks();
  }

  base::TimeDelta delay = NextTaskTime() - now_src_->NowTicks();
  if (delay > base::TimeDelta())
    return delay;
  return base::TimeDelta();
}

const size_t OrderedSimpleTaskRunner::kAbsoluteMaxTasks =
    std::numeric_limits<size_t>::max();

bool OrderedSimpleTaskRunner::RunTasksWhile(
    base::Callback<bool(void)> condition) {
  std::vector<base::Callback<bool(void)>> conditions(1);
  conditions[0] = condition;
  return RunTasksWhile(conditions);
}

bool OrderedSimpleTaskRunner::RunTasksWhile(
    const std::vector<base::Callback<bool(void)>>& conditions) {
  TRACE_EVENT2("cc",
               "OrderedSimpleTaskRunner::RunPendingTasks",
               "this",
               AsValue(),
               "nested",
               inside_run_tasks_until_);
  DCHECK(thread_checker_.CalledOnValidThread());

  if (inside_run_tasks_until_)
    return true;

  base::AutoReset<bool> reset_inside_run_tasks_until_(&inside_run_tasks_until_,
                                                      true);

  // Make a copy so we can append some extra run checks.
  std::vector<base::Callback<bool(void)>> modifiable_conditions(conditions);

  // Provide a timeout base on number of tasks run so this doesn't loop
  // forever.
  modifiable_conditions.push_back(TaskRunCountBelow(max_tasks_));

  // If to advance now or not
  if (!advance_now_) {
    modifiable_conditions.push_back(NowBefore(now_src_->NowTicks()));
  } else {
    modifiable_conditions.push_back(AdvanceNow());
  }

  while (pending_tasks_.size() > 0) {
    // Check if we should continue to run pending tasks.
    bool condition_success = true;
    for (std::vector<base::Callback<bool(void)>>::iterator it =
             modifiable_conditions.begin();
         it != modifiable_conditions.end();
         it++) {
      condition_success = it->Run();
      if (!condition_success)
        break;
    }

    // Conditions could modify the pending task length, so we need to recheck
    // that there are tasks to run.
    if (!condition_success || !HasPendingTasks()) {
      break;
    }

    std::set<TestOrderablePendingTask>::iterator task_to_run =
        pending_tasks_.begin();
    {
      TRACE_EVENT1("cc",
                   "OrderedSimpleTaskRunner::RunPendingTasks running",
                   "task",
                   task_to_run->AsValue());
      task_to_run->task.Run();
    }

    pending_tasks_.erase(task_to_run);
  }

  return HasPendingTasks();
}

bool OrderedSimpleTaskRunner::RunPendingTasks() {
  return RunTasksWhile(TaskExistedInitially());
}

bool OrderedSimpleTaskRunner::RunUntilIdle() {
  return RunTasksWhile(std::vector<base::Callback<bool(void)>>());
}

bool OrderedSimpleTaskRunner::RunUntilTime(base::TimeTicks time) {
  // If we are not auto advancing, force now forward to the time.
  if (!advance_now_ && now_src_->NowTicks() < time)
    now_src_->Advance(time - now_src_->NowTicks());

  // Run tasks
  bool result = RunTasksWhile(NowBefore(time));

  // If the next task is after the stopping time and auto-advancing now, then
  // force time to be the stopping time.
  if (!result && advance_now_ && now_src_->NowTicks() < time) {
    now_src_->Advance(time - now_src_->NowTicks());
  }

  return result;
}

bool OrderedSimpleTaskRunner::RunForPeriod(base::TimeDelta period) {
  return RunUntilTime(now_src_->NowTicks() + period);
}

// base::trace_event tracing functionality
scoped_refptr<base::trace_event::ConvertableToTraceFormat>
OrderedSimpleTaskRunner::AsValue() const {
  scoped_refptr<base::trace_event::TracedValue> state =
      new base::trace_event::TracedValue();
  AsValueInto(state.get());
  return state;
}

void OrderedSimpleTaskRunner::AsValueInto(
    base::trace_event::TracedValue* state) const {
  state->SetInteger("pending_tasks",
                    base::saturated_cast<int>(pending_tasks_.size()));

  state->BeginArray("tasks");
  for (std::set<TestOrderablePendingTask>::const_iterator it =
           pending_tasks_.begin();
       it != pending_tasks_.end();
       ++it) {
    state->BeginDictionary();
    it->AsValueInto(state);
    state->EndDictionary();
  }
  state->EndArray();

  state->BeginDictionary("now_src");
  state->SetDouble("now_in_ms", (now_src_->NowTicks() - base::TimeTicks())
                                    .InMillisecondsF());
  state->EndDictionary();

  state->SetBoolean("advance_now", advance_now_);
  state->SetBoolean("inside_run_tasks_until", inside_run_tasks_until_);
  state->SetString("max_tasks", base::SizeTToString(max_tasks_));
}

base::Callback<bool(void)> OrderedSimpleTaskRunner::TaskRunCountBelow(
    size_t max_tasks) {
  return base::Bind(&OrderedSimpleTaskRunner::TaskRunCountBelowCallback,
                    max_tasks,
                    base::Owned(new size_t(0)));
}

bool OrderedSimpleTaskRunner::TaskRunCountBelowCallback(size_t max_tasks,
                                                        size_t* tasks_run) {
  return (*tasks_run)++ < max_tasks;
}

base::Callback<bool(void)> OrderedSimpleTaskRunner::TaskExistedInitially() {
  // base::Bind takes a copy of pending_tasks_
  return base::Bind(&OrderedSimpleTaskRunner::TaskExistedInitiallyCallback,
                    base::Unretained(this),
                    pending_tasks_);
}

bool OrderedSimpleTaskRunner::TaskExistedInitiallyCallback(
    const std::set<TestOrderablePendingTask>& existing_tasks) {
  return existing_tasks.find(*pending_tasks_.begin()) != existing_tasks.end();
}

base::Callback<bool(void)> OrderedSimpleTaskRunner::NowBefore(
    base::TimeTicks stop_at) {
  return base::Bind(&OrderedSimpleTaskRunner::NowBeforeCallback,
                    base::Unretained(this),
                    stop_at);
}
bool OrderedSimpleTaskRunner::NowBeforeCallback(base::TimeTicks stop_at) {
  return NextTaskTime() <= stop_at;
}

base::Callback<bool(void)> OrderedSimpleTaskRunner::AdvanceNow() {
  return base::Bind(&OrderedSimpleTaskRunner::AdvanceNowCallback,
                    base::Unretained(this));
}

bool OrderedSimpleTaskRunner::AdvanceNowCallback() {
  base::TimeTicks next_task_time = NextTaskTime();
  if (now_src_->NowTicks() < next_task_time) {
    now_src_->Advance(next_task_time - now_src_->NowTicks());
  }
  return true;
}

}  // namespace cc
