// Copyright 2018 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 "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"

#include "base/bind_helpers.h"
#include "base/memory/scoped_refptr.h"
#include "base/single_thread_task_runner.h"
#include "base/test/bind_test_util.h"
#include "base/test/mock_callback.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/threading/thread_task_runner_handle.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#include "base/debug/stack_trace.h"

#include <queue>

using testing::_;
using testing::Invoke;
using testing::ElementsAre;

namespace base {
namespace sequence_manager {

namespace {

class ThreadControllerForTest
    : public internal::ThreadControllerWithMessagePumpImpl {
 public:
  ThreadControllerForTest(std::unique_ptr<MessagePump> pump,
                          const TickClock* clock)
      : ThreadControllerWithMessagePumpImpl(std::move(pump), clock) {}

  using ThreadControllerWithMessagePumpImpl::DoDelayedWork;
  using ThreadControllerWithMessagePumpImpl::DoIdleWork;
  using ThreadControllerWithMessagePumpImpl::DoWork;
  using ThreadControllerWithMessagePumpImpl::EnsureWorkScheduled;
  using ThreadControllerWithMessagePumpImpl::Quit;
};

class MockMessagePump : public MessagePump {
 public:
  MockMessagePump() {}
  ~MockMessagePump() override {}

  MOCK_METHOD1(Run, void(MessagePump::Delegate*));
  MOCK_METHOD0(Quit, void());
  MOCK_METHOD0(ScheduleWork, void());
  MOCK_METHOD1(ScheduleDelayedWork, void(const TimeTicks&));
  MOCK_METHOD1(SetTimerSlack, void(TimerSlack));
};

// TODO(crbug.com/901373): Deduplicate FakeTaskRunners.
class FakeTaskRunner : public SingleThreadTaskRunner {
 public:
  bool PostDelayedTask(const Location& from_here,
                       OnceClosure task,
                       TimeDelta delay) override {
    return true;
  }

  bool PostNonNestableDelayedTask(const Location& from_here,
                                  OnceClosure task,
                                  TimeDelta delay) override {
    return true;
  }

  bool RunsTasksInCurrentSequence() const override { return true; }

 protected:
  ~FakeTaskRunner() override = default;
};

class FakeSequencedTaskSource : public internal::SequencedTaskSource {
 public:
  explicit FakeSequencedTaskSource(TickClock* clock) : clock_(clock) {}
  ~FakeSequencedTaskSource() override = default;

  Optional<PendingTask> TakeTask() override {
    if (tasks_.empty())
      return nullopt;
    if (tasks_.front().delayed_run_time > clock_->NowTicks())
      return nullopt;
    PendingTask task = std::move(tasks_.front());
    tasks_.pop();
    return task;
  }

  void DidRunTask() override {}

  TimeDelta DelayTillNextTask(LazyNow* lazy_now) const override {
    if (tasks_.empty())
      return TimeDelta::Max();
    if (tasks_.front().delayed_run_time.is_null())
      return TimeDelta();
    if (lazy_now->Now() > tasks_.front().delayed_run_time)
      return TimeDelta();
    return tasks_.front().delayed_run_time - lazy_now->Now();
  }

  void AddTask(PendingTask task) {
    DCHECK(tasks_.empty() || task.delayed_run_time.is_null() ||
           tasks_.back().delayed_run_time < task.delayed_run_time);
    tasks_.push(std::move(task));
  }

  bool HasPendingHighResolutionTasks() override { return false; }

  bool OnSystemIdle() override { return false; }

 private:
  TickClock* clock_;
  std::queue<PendingTask> tasks_;
};

TimeTicks Seconds(int seconds) {
  return TimeTicks() + TimeDelta::FromSeconds(seconds);
}

TimeTicks Days(int seconds) {
  return TimeTicks() + TimeDelta::FromDays(seconds);
}

}  // namespace

class ThreadControllerWithMessagePumpTest : public testing::Test {
 public:
  ThreadControllerWithMessagePumpTest()
      : message_pump_(new testing::StrictMock<MockMessagePump>()),
        thread_controller_(std::unique_ptr<MessagePump>(message_pump_),
                           &clock_),
        task_source_(&clock_) {
    thread_controller_.SetWorkBatchSize(1);
    thread_controller_.SetSequencedTaskSource(&task_source_);
  }

 protected:
  MockMessagePump* message_pump_;
  SimpleTestTickClock clock_;
  ThreadControllerForTest thread_controller_;
  FakeSequencedTaskSource task_source_;
};

TEST_F(ThreadControllerWithMessagePumpTest, ScheduleDelayedWork) {
  TimeTicks next_run_time;

  MockCallback<OnceClosure> task1;
  task_source_.AddTask(PendingTask(FROM_HERE, task1.Get(), Seconds(10)));
  MockCallback<OnceClosure> task2;
  task_source_.AddTask(PendingTask(FROM_HERE, task2.Get(), TimeTicks()));
  MockCallback<OnceClosure> task3;
  task_source_.AddTask(PendingTask(FROM_HERE, task3.Get(), Seconds(20)));

  // Call a no-op DoWork. Expect that it doesn't do any work, but
  // schedules a delayed wake-up appropriately.
  clock_.SetNowTicks(Seconds(5));
  EXPECT_CALL(*message_pump_, ScheduleDelayedWork(Seconds(10)));
  EXPECT_FALSE(thread_controller_.DoWork());
  testing::Mock::VerifyAndClearExpectations(message_pump_);

  // Call DoDelayedWork after the expiration of the delay.
  // Expect that a task will run and the next delay will equal to
  // TimeTicks() as we have immediate work to do.
  clock_.SetNowTicks(Seconds(11));
  EXPECT_CALL(task1, Run()).Times(1);
  EXPECT_TRUE(thread_controller_.DoDelayedWork(&next_run_time));
  EXPECT_EQ(next_run_time, TimeTicks());
  testing::Mock::VerifyAndClearExpectations(message_pump_);
  testing::Mock::VerifyAndClearExpectations(&task1);

  // Call DoWork immediately after the previous call. Expect a new task
  // to be run.
  EXPECT_CALL(task2, Run()).Times(1);
  EXPECT_CALL(*message_pump_, ScheduleDelayedWork(Seconds(20)));
  EXPECT_TRUE(thread_controller_.DoWork());
  testing::Mock::VerifyAndClearExpectations(message_pump_);
  testing::Mock::VerifyAndClearExpectations(&task2);

  // Call DoDelayedWork for the last task and expect to be told
  // about the lack of further delayed work (next run time being TimeTicks()).
  clock_.SetNowTicks(Seconds(21));
  EXPECT_CALL(task3, Run()).Times(1);
  EXPECT_TRUE(thread_controller_.DoDelayedWork(&next_run_time));
  EXPECT_EQ(next_run_time, TimeTicks());
  testing::Mock::VerifyAndClearExpectations(message_pump_);
  testing::Mock::VerifyAndClearExpectations(&task3);
}

TEST_F(ThreadControllerWithMessagePumpTest, SetNextDelayedDoWork) {
  EXPECT_CALL(*message_pump_, ScheduleDelayedWork(Seconds(123)));

  LazyNow lazy_now(&clock_);
  thread_controller_.SetNextDelayedDoWork(&lazy_now, Seconds(123));
}

TEST_F(ThreadControllerWithMessagePumpTest, SetNextDelayedDoWork_CapAtOneDay) {
  EXPECT_CALL(*message_pump_, ScheduleDelayedWork(Days(1)));

  LazyNow lazy_now(&clock_);
  thread_controller_.SetNextDelayedDoWork(&lazy_now, Days(2));
}

TEST_F(ThreadControllerWithMessagePumpTest, DelayedWork_CapAtOneDay) {
  MockCallback<OnceClosure> task1;
  task_source_.AddTask(PendingTask(FROM_HERE, task1.Get(), Days(10)));

  EXPECT_CALL(*message_pump_, ScheduleDelayedWork(Days(1)));
  EXPECT_FALSE(thread_controller_.DoWork());
}

TEST_F(ThreadControllerWithMessagePumpTest, NestedExecution) {
  // This test posts three immediate tasks. The first creates a nested RunLoop
  // and the test expects that the second and third tasks are run outside of
  // the nested loop.
  std::vector<std::string> log;

  ThreadTaskRunnerHandle handle(MakeRefCounted<FakeTaskRunner>());

  EXPECT_CALL(*message_pump_, Run(_))
      .WillOnce(Invoke([&log, this](MessagePump::Delegate* delegate) {
        log.push_back("entering top-level runloop");
        EXPECT_EQ(delegate, &thread_controller_);
        EXPECT_TRUE(delegate->DoWork());
        EXPECT_TRUE(delegate->DoWork());
        EXPECT_TRUE(delegate->DoWork());
        EXPECT_FALSE(delegate->DoWork());
        log.push_back("exiting top-level runloop");
      }))
      .WillOnce(Invoke([&log, this](MessagePump::Delegate* delegate) {
        log.push_back("entering nested runloop");
        EXPECT_EQ(delegate, &thread_controller_);
        EXPECT_FALSE(thread_controller_.IsTaskExecutionAllowed());
        EXPECT_FALSE(delegate->DoWork());
        log.push_back("exiting nested runloop");
      }));

  task_source_.AddTask(
      PendingTask(FROM_HERE,
                  base::BindOnce(
                      [](std::vector<std::string>* log,
                         ThreadControllerForTest* controller) {
                        EXPECT_FALSE(controller->IsTaskExecutionAllowed());
                        log->push_back("task1");
                        RunLoop().Run();
                      },
                      &log, &thread_controller_),
                  TimeTicks()));
  task_source_.AddTask(
      PendingTask(FROM_HERE,
                  base::BindOnce(
                      [](std::vector<std::string>* log,
                         ThreadControllerForTest* controller) {
                        EXPECT_FALSE(controller->IsTaskExecutionAllowed());
                        log->push_back("task2");
                      },
                      &log, &thread_controller_),
                  TimeTicks()));
  task_source_.AddTask(
      PendingTask(FROM_HERE,
                  base::BindOnce(
                      [](std::vector<std::string>* log,
                         ThreadControllerForTest* controller) {
                        EXPECT_FALSE(controller->IsTaskExecutionAllowed());
                        log->push_back("task3");
                      },
                      &log, &thread_controller_),
                  TimeTicks()));

  EXPECT_TRUE(thread_controller_.IsTaskExecutionAllowed());
  RunLoop().Run();

  EXPECT_THAT(log,
              ElementsAre("entering top-level runloop", "task1",
                          "entering nested runloop", "exiting nested runloop",
                          "task2", "task3", "exiting top-level runloop"));
  testing::Mock::VerifyAndClearExpectations(message_pump_);
}

TEST_F(ThreadControllerWithMessagePumpTest,
       NestedExecutionWithApplicationTasks) {
  // THis test is similar to the previous one, but execution is explicitly
  // allowed (by specifying appropriate RunLoop type), and tasks are run inside
  // nested runloop.
  std::vector<std::string> log;

  ThreadTaskRunnerHandle handle(MakeRefCounted<FakeTaskRunner>());

  EXPECT_CALL(*message_pump_, Run(_))
      .WillOnce(Invoke([&log, this](MessagePump::Delegate* delegate) {
        log.push_back("entering top-level runloop");
        EXPECT_EQ(delegate, &thread_controller_);
        EXPECT_TRUE(delegate->DoWork());
        EXPECT_FALSE(delegate->DoWork());
        log.push_back("exiting top-level runloop");
      }))
      .WillOnce(Invoke([&log, this](MessagePump::Delegate* delegate) {
        log.push_back("entering nested runloop");
        EXPECT_EQ(delegate, &thread_controller_);
        EXPECT_TRUE(thread_controller_.IsTaskExecutionAllowed());
        EXPECT_TRUE(delegate->DoWork());
        EXPECT_TRUE(delegate->DoWork());
        EXPECT_FALSE(delegate->DoWork());
        log.push_back("exiting nested runloop");
      }));
  // An extra schedule work will be called when entering a nested runloop.
  EXPECT_CALL(*message_pump_, ScheduleWork());

  task_source_.AddTask(
      PendingTask(FROM_HERE,
                  base::BindOnce(
                      [](std::vector<std::string>* log,
                         ThreadControllerForTest* controller) {
                        EXPECT_FALSE(controller->IsTaskExecutionAllowed());
                        log->push_back("task1");
                        RunLoop(RunLoop::Type::kNestableTasksAllowed).Run();
                      },
                      &log, &thread_controller_),
                  TimeTicks()));
  task_source_.AddTask(
      PendingTask(FROM_HERE,
                  base::BindOnce(
                      [](std::vector<std::string>* log,
                         ThreadControllerForTest* controller) {
                        EXPECT_FALSE(controller->IsTaskExecutionAllowed());
                        log->push_back("task2");
                      },
                      &log, &thread_controller_),
                  TimeTicks()));
  task_source_.AddTask(
      PendingTask(FROM_HERE,
                  base::BindOnce(
                      [](std::vector<std::string>* log,
                         ThreadControllerForTest* controller) {
                        EXPECT_FALSE(controller->IsTaskExecutionAllowed());
                        log->push_back("task3");
                      },
                      &log, &thread_controller_),
                  TimeTicks()));

  EXPECT_TRUE(thread_controller_.IsTaskExecutionAllowed());
  RunLoop().Run();

  EXPECT_THAT(
      log, ElementsAre("entering top-level runloop", "task1",
                       "entering nested runloop", "task2", "task3",
                       "exiting nested runloop", "exiting top-level runloop"));
  testing::Mock::VerifyAndClearExpectations(message_pump_);
}

TEST_F(ThreadControllerWithMessagePumpTest, SetDefaultTaskRunner) {
  scoped_refptr<SingleThreadTaskRunner> task_runner1 =
      MakeRefCounted<FakeTaskRunner>();
  thread_controller_.SetDefaultTaskRunner(task_runner1);
  EXPECT_EQ(task_runner1, ThreadTaskRunnerHandle::Get());

  // Check that we are correctly supporting overriding.
  scoped_refptr<SingleThreadTaskRunner> task_runner2 =
      MakeRefCounted<FakeTaskRunner>();
  thread_controller_.SetDefaultTaskRunner(task_runner2);
  EXPECT_EQ(task_runner2, ThreadTaskRunnerHandle::Get());
}

TEST_F(ThreadControllerWithMessagePumpTest, EnsureWorkScheduled) {
  task_source_.AddTask(PendingTask(FROM_HERE, DoNothing(), TimeTicks()));

  // Ensure that the first ScheduleWork() call results in the pump being called.
  EXPECT_CALL(*message_pump_, ScheduleWork());
  thread_controller_.ScheduleWork();
  testing::Mock::VerifyAndClearExpectations(message_pump_);

  // Ensure that the subsequent ScheduleWork() does not call the pump.
  thread_controller_.ScheduleWork();
  testing::Mock::VerifyAndClearExpectations(message_pump_);

  // Ensure that EnsureWorkScheduled() forces a call to a pump.
  EXPECT_CALL(*message_pump_, ScheduleWork());
  thread_controller_.EnsureWorkScheduled();
  testing::Mock::VerifyAndClearExpectations(message_pump_);
}

TEST_F(ThreadControllerWithMessagePumpTest, WorkBatching) {
  ThreadTaskRunnerHandle handle(MakeRefCounted<FakeTaskRunner>());

  const int kBatchSize = 5;
  thread_controller_.SetWorkBatchSize(kBatchSize);

  int task_count = 0;
  EXPECT_CALL(*message_pump_, Run(_))
      .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
        EXPECT_TRUE(delegate->DoWork());
        EXPECT_EQ(5, task_count);
      }));

  for (int i = 0; i < kBatchSize; i++) {
    task_source_.AddTask(PendingTask(
        FROM_HERE, BindLambdaForTesting([&] { task_count++; }), TimeTicks()));
  }

  RunLoop run_loop;
  run_loop.Run();
  testing::Mock::VerifyAndClearExpectations(message_pump_);
}

TEST_F(ThreadControllerWithMessagePumpTest, QuitInterruptsBatch) {
  // This check ensures that RunLoop::Quit() makes us drop back to a work batch
  // size of 1.
  ThreadTaskRunnerHandle handle(MakeRefCounted<FakeTaskRunner>());

  const int kBatchSize = 5;
  thread_controller_.SetWorkBatchSize(kBatchSize);

  int task_count = 0;
  EXPECT_CALL(*message_pump_, Run(_))
      .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
        TimeTicks next_time;
        EXPECT_TRUE(delegate->DoWork());
        EXPECT_EQ(1, task_count);

        // Somewhat counter-intuitive, but if the pump keeps calling us after
        // Quit(), the delegate should still run tasks as normally. This is
        // needed to support nested OS-level runloops that still pump
        // application tasks (e.g., showing a popup menu on Mac).
        EXPECT_TRUE(delegate->DoDelayedWork(&next_time));
        EXPECT_EQ(2, task_count);
        EXPECT_TRUE(delegate->DoWork());
        EXPECT_EQ(3, task_count);
      }));
  EXPECT_CALL(*message_pump_, Quit());

  RunLoop run_loop;
  for (int i = 0; i < kBatchSize; i++) {
    task_source_.AddTask(PendingTask(FROM_HERE, BindLambdaForTesting([&] {
                                       if (!task_count++)
                                         run_loop.Quit();
                                     }),
                                     TimeTicks()));
  }

  run_loop.Run();
  testing::Mock::VerifyAndClearExpectations(message_pump_);
}

TEST_F(ThreadControllerWithMessagePumpTest, EarlyQuit) {
  // This test ensures that a opt-of-runloop Quit() (which is possible with some
  // pump implementations) doesn't affect the next RunLoop::Run call.

  ThreadTaskRunnerHandle handle(MakeRefCounted<FakeTaskRunner>());

  std::vector<std::string> log;

  // This quit should be a no-op for future calls.
  EXPECT_CALL(*message_pump_, Quit());
  thread_controller_.Quit();
  testing::Mock::VerifyAndClearExpectations(message_pump_);

  EXPECT_CALL(*message_pump_, Run(_))
      .WillOnce(Invoke([this](MessagePump::Delegate* delegate) {
        EXPECT_EQ(delegate, &thread_controller_);
        EXPECT_TRUE(delegate->DoWork());
        EXPECT_TRUE(delegate->DoWork());
        EXPECT_FALSE(delegate->DoWork());
      }));

  RunLoop run_loop;

  task_source_.AddTask(PendingTask(
      FROM_HERE,
      base::BindOnce(
          [](std::vector<std::string>* log) { log->push_back("task1"); }, &log),
      TimeTicks()));
  task_source_.AddTask(PendingTask(
      FROM_HERE,
      base::BindOnce(
          [](std::vector<std::string>* log) { log->push_back("task2"); }, &log),
      TimeTicks()));

  run_loop.RunUntilIdle();

  EXPECT_THAT(log, ElementsAre("task1", "task2"));
  testing::Mock::VerifyAndClearExpectations(message_pump_);
}

}  // namespace sequence_manager
}  // namespace base
