// 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 <limits>
#include <set>
#include <sstream>
#include <string>
#include <vector>

#include "base/auto_reset.h"
#include "base/debug/trace_event.h"
#include "base/debug/trace_event_argument.h"
#include "base/strings/string_number_conversions.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::debug::ConvertableToTraceFormat>
TestOrderablePendingTask::AsValue() const {
  scoped_refptr<base::debug::TracedValue> state =
      new base::debug::TracedValue();
  AsValueInto(state.get());
  return state;
}

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

OrderedSimpleTaskRunner::OrderedSimpleTaskRunner()
    : advance_now_(true),
      now_src_(TestNowSource::Create(0)),
      inside_run_tasks_until_(false) {
}

OrderedSimpleTaskRunner::OrderedSimpleTaskRunner(
    scoped_refptr<TestNowSource> now_src,
    bool advance_now)
    : advance_now_(advance_now),
      now_src_(now_src),
      max_tasks_(kAbsoluteMaxTasks),
      inside_run_tasks_until_(false) {
}

OrderedSimpleTaskRunner::~OrderedSimpleTaskRunner() {}

// 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_->Now(), 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_->Now(),
                              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;
}

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

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

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

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

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

  base::TimeDelta delay = NextTaskTime() - now_src_->Now();
  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_->Now()));
  } 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_->Now() < time)
    now_src_->SetNow(time);

  // 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_->Now() < time) {
    now_src_->SetNow(time);
  }

  return result;
}

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

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

void OrderedSimpleTaskRunner::AsValueInto(
    base::debug::TracedValue* state) const {
  state->SetInteger("pending_tasks", pending_tasks_.size());
  for (std::set<TestOrderablePendingTask>::const_iterator it =
           pending_tasks_.begin();
       it != pending_tasks_.end();
       ++it) {
    state->BeginDictionary(
        base::SizeTToString(std::distance(pending_tasks_.begin(), it)).c_str());
    it->AsValueInto(state);
    state->EndDictionary();
  }
  now_src_->AsValueInto(state);
}

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_->Now() < next_task_time) {
    now_src_->SetNow(next_task_time);
  }
  return true;
}

}  // namespace cc
