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

#ifndef CC_TEST_ORDERED_SIMPLE_TASK_RUNNER_H_
#define CC_TEST_ORDERED_SIMPLE_TASK_RUNNER_H_

#include <limits>
#include <set>
#include <vector>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/test/test_simple_task_runner.h"
#include "cc/test/test_now_source.h"

namespace cc {

// Subclass of TestPendingTask which has a unique ID for every task, supports
// being used inside a std::set and has debug tracing support.
class TestOrderablePendingTask : public base::TestPendingTask {
 public:
  TestOrderablePendingTask();
  TestOrderablePendingTask(const tracked_objects::Location& location,
                           const base::Closure& task,
                           base::TimeTicks post_time,
                           base::TimeDelta delay,
                           TestNestability nestability);
  ~TestOrderablePendingTask();

  // operators needed by std::set and comparison
  bool operator==(const TestOrderablePendingTask& other) const;
  bool operator<(const TestOrderablePendingTask& other) const;

  // debug tracing functions
  scoped_refptr<base::debug::ConvertableToTraceFormat> AsValue() const;
  void AsValueInto(base::debug::TracedValue* state) const;

 private:
  static size_t task_id_counter;
  const size_t task_id_;
};

// This runs pending tasks based on task's post_time + delay.
// We should not execute a delayed task sooner than some of the queued tasks
// which don't have a delay even though it is queued early.
class OrderedSimpleTaskRunner : public base::SingleThreadTaskRunner {
 public:
  OrderedSimpleTaskRunner();
  OrderedSimpleTaskRunner(scoped_refptr<TestNowSource> now_src,
                          bool advance_now);

  // base::TestSimpleTaskRunner implementation:
  virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
                               const base::Closure& task,
                               base::TimeDelta delay) OVERRIDE;
  virtual bool PostNonNestableDelayedTask(
      const tracked_objects::Location& from_here,
      const base::Closure& task,
      base::TimeDelta delay) OVERRIDE;

  virtual bool RunsTasksOnCurrentThread() const OVERRIDE;

  // Set a maximum number of tasks to run at once. Useful as a timeout to
  // prevent infinite task loops.
  static const size_t kAbsoluteMaxTasks;
  void SetRunTaskLimit(size_t max_tasks) { max_tasks_ = max_tasks; }
  void ClearRunTaskLimit() { max_tasks_ = kAbsoluteMaxTasks; }

  // Allow task runner to advance now when running tasks.
  void SetAutoAdvanceNowToPendingTasks(bool advance_now) {
    advance_now_ = advance_now;
  }

  bool HasPendingTasks() const;
  base::TimeTicks NextTaskTime();
  base::TimeDelta DelayToNextTaskTime();

  // Run tasks while the callback returns true or too many tasks have been run.
  // Returns true if there are still pending tasks left.
  bool RunTasksWhile(base::Callback<bool(void)> condition);

  // Run tasks while *all* of the callbacks return true or too many tasks have
  // been run. Exits on the *first* condition which returns false, skipping
  // calling all remaining conditions. Conditions can have side effects,
  // including modifying the task queue.
  // Returns true if there are still pending tasks left.
  bool RunTasksWhile(
      const std::vector<base::Callback<bool(void)> >& conditions);

  // Convenience functions to run tasks with common conditions.

  // Run tasks which existed at the start of this call.
  // Return code indicates tasks still exist to run.
  bool RunPendingTasks();
  // Keep running tasks until no tasks are left.
  // Return code indicates tasks still exist to run which also indicates if
  // runner reached idle.
  bool RunUntilIdle();
  // Keep running tasks until given time period.
  // Return code indicates tasks still exist to run.
  bool RunUntilTime(base::TimeTicks time);
  bool RunForPeriod(base::TimeDelta period);

  // base::debug tracing functionality
  scoped_refptr<base::debug::ConvertableToTraceFormat> AsValue() const;
  virtual void AsValueInto(base::debug::TracedValue* state) const;

  // Common conditions to run for, exposed publicly to allow external users to
  // use their own combinations.
  // -------------------------------------------------------------------------

  // Keep running until the given number of tasks have run.
  // You generally shouldn't use this check as it will cause your tests to fail
  // when code is changed adding a new task. It is useful as a "timeout" type
  // solution.
  base::Callback<bool(void)> TaskRunCountBelow(size_t max_tasks);

  // Keep running until a task which didn't exist initially would run.
  base::Callback<bool(void)> TaskExistedInitially();

  // Stop running tasks when NextTaskTime() >= stop_at
  base::Callback<bool(void)> NowBefore(base::TimeTicks stop_at);

  // Advance Now() to the next task to run.
  base::Callback<bool(void)> AdvanceNow();

 protected:
  static bool TaskRunCountBelowCallback(size_t max_tasks, size_t* task_run);
  bool TaskExistedInitiallyCallback(
      const std::set<TestOrderablePendingTask>& existing_tasks);
  bool NowBeforeCallback(base::TimeTicks stop_at);
  bool AdvanceNowCallback();

  virtual ~OrderedSimpleTaskRunner();

  base::ThreadChecker thread_checker_;

  bool advance_now_;
  scoped_refptr<TestNowSource> now_src_;

  size_t max_tasks_;

  bool inside_run_tasks_until_;
  std::set<TestOrderablePendingTask> pending_tasks_;

 private:
  DISALLOW_COPY_AND_ASSIGN(OrderedSimpleTaskRunner);
};

}  // namespace cc

#endif  // CC_TEST_ORDERED_SIMPLE_TASK_RUNNER_H_
