// Copyright 2011 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_SCHEDULER_TEST_COMMON_H_
#define CC_TEST_SCHEDULER_TEST_COMMON_H_

#include <string>

#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "cc/scheduler/delay_based_time_source.h"
#include "cc/scheduler/scheduler.h"
#include "cc/test/ordered_simple_task_runner.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cc {

class FakeTimeSourceClient : public TimeSourceClient {
 public:
  FakeTimeSourceClient() : tick_called_(false) {}
  void Reset() { tick_called_ = false; }
  bool TickCalled() const { return tick_called_; }

  // TimeSourceClient implementation.
  virtual void OnTimerTick() override;

 protected:
  bool tick_called_;
};

class FakeDelayBasedTimeSource : public DelayBasedTimeSource {
 public:
  static scoped_refptr<FakeDelayBasedTimeSource> Create(
      base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner) {
    return make_scoped_refptr(new FakeDelayBasedTimeSource(interval,
                                                           task_runner));
  }

  void SetNow(base::TimeTicks time) { now_ = time; }
  virtual base::TimeTicks Now() const override;

 protected:
  FakeDelayBasedTimeSource(base::TimeDelta interval,
                           base::SingleThreadTaskRunner* task_runner)
      : DelayBasedTimeSource(interval, task_runner) {}
  virtual ~FakeDelayBasedTimeSource() {}

  base::TimeTicks now_;
};

class TestDelayBasedTimeSource : public DelayBasedTimeSource {
 public:
  static scoped_refptr<TestDelayBasedTimeSource> Create(
      scoped_refptr<TestNowSource> now_src,
      base::TimeDelta interval,
      OrderedSimpleTaskRunner* task_runner) {
    return make_scoped_refptr(
        new TestDelayBasedTimeSource(now_src, interval, task_runner));
  }

 protected:
  TestDelayBasedTimeSource(scoped_refptr<TestNowSource> now_src,
                           base::TimeDelta interval,
                           OrderedSimpleTaskRunner* task_runner);

  // Overridden from DelayBasedTimeSource
  virtual ~TestDelayBasedTimeSource();
  virtual base::TimeTicks Now() const override;
  virtual std::string TypeString() const override;

  scoped_refptr<TestNowSource> now_src_;
};

struct FakeBeginFrameSource : public BeginFrameSourceMixIn {
  bool remaining_frames_ = false;

  BeginFrameObserver* GetObserver() { return observer_; }

  BeginFrameArgs TestLastUsedBeginFrameArgs() {
    if (observer_) {
      return observer_->LastUsedBeginFrameArgs();
    }
    return BeginFrameArgs();
  }
  void TestOnBeginFrame(const BeginFrameArgs& args) {
    return CallOnBeginFrame(args);
  }

  // BeginFrameSource
  virtual void DidFinishFrame(size_t remaining_frames) override;
  virtual void AsValueInto(base::debug::TracedValue* dict) const override;

  virtual ~FakeBeginFrameSource() {}
};

class TestBackToBackBeginFrameSource : public BackToBackBeginFrameSource {
 public:
  virtual ~TestBackToBackBeginFrameSource();

  static scoped_ptr<TestBackToBackBeginFrameSource> Create(
      scoped_refptr<TestNowSource> now_src,
      base::SingleThreadTaskRunner* task_runner) {
    return make_scoped_ptr(
        new TestBackToBackBeginFrameSource(now_src, task_runner));
  }

 protected:
  TestBackToBackBeginFrameSource(scoped_refptr<TestNowSource> now_src,
                                 base::SingleThreadTaskRunner* task_runner);

  virtual base::TimeTicks Now() override;

  scoped_refptr<TestNowSource> now_src_;
};

class TestSyntheticBeginFrameSource : public SyntheticBeginFrameSource {
 public:
  virtual ~TestSyntheticBeginFrameSource();

  static scoped_ptr<TestSyntheticBeginFrameSource> Create(
      scoped_refptr<TestNowSource> now_src,
      OrderedSimpleTaskRunner* task_runner,
      base::TimeDelta initial_interval) {
    return make_scoped_ptr(
        new TestSyntheticBeginFrameSource(TestDelayBasedTimeSource::Create(
            now_src, initial_interval, task_runner)));
  }

 protected:
  TestSyntheticBeginFrameSource(
      scoped_refptr<DelayBasedTimeSource> time_source);
};

class TestScheduler;
class TestSchedulerFrameSourcesConstructor
    : public SchedulerFrameSourcesConstructor {
 public:
  virtual ~TestSchedulerFrameSourcesConstructor();

 protected:
  virtual BeginFrameSource* ConstructPrimaryFrameSource(
      Scheduler* scheduler) override;
  virtual BeginFrameSource* ConstructBackgroundFrameSource(
      Scheduler* scheduler) override;

  OrderedSimpleTaskRunner* test_task_runner_;
  TestNowSource* now_src_;

 protected:
  explicit TestSchedulerFrameSourcesConstructor(
      OrderedSimpleTaskRunner* test_task_runner,
      TestNowSource* now_src);
  friend class TestScheduler;
};

class TestScheduler : public Scheduler {
 public:
  static scoped_ptr<TestScheduler> Create(
      scoped_refptr<TestNowSource> now_src,
      SchedulerClient* client,
      const SchedulerSettings& scheduler_settings,
      int layer_tree_host_id) {
    // A bunch of tests require Now() to be > BeginFrameArgs::DefaultInterval()
    now_src->AdvanceNow(base::TimeDelta::FromMilliseconds(100));

    scoped_refptr<OrderedSimpleTaskRunner> test_task_runner =
        new OrderedSimpleTaskRunner(now_src, true);
    TestSchedulerFrameSourcesConstructor frame_sources_constructor(
        test_task_runner.get(), now_src.get());
    return make_scoped_ptr(new TestScheduler(now_src,
                                             client,
                                             scheduler_settings,
                                             layer_tree_host_id,
                                             test_task_runner,
                                             &frame_sources_constructor));
  }

  // Extra test helper functionality
  bool IsBeginRetroFrameArgsEmpty() const {
    return begin_retro_frame_args_.empty();
  }

  BeginFrameSource& frame_source() { return *frame_source_; }
  OrderedSimpleTaskRunner& task_runner() { return *test_task_runner_; }

  virtual ~TestScheduler();

 protected:
  // Overridden from Scheduler.
  virtual base::TimeTicks Now() const override;

 private:
  TestScheduler(
      scoped_refptr<TestNowSource> now_src,
      SchedulerClient* client,
      const SchedulerSettings& scheduler_settings,
      int layer_tree_host_id,
      const scoped_refptr<OrderedSimpleTaskRunner>& test_task_runner,
      TestSchedulerFrameSourcesConstructor* frame_sources_constructor);

  scoped_refptr<TestNowSource> now_src_;
  OrderedSimpleTaskRunner* test_task_runner_;
};

}  // namespace cc

#endif  // CC_TEST_SCHEDULER_TEST_COMMON_H_
