// Copyright 2015 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 "third_party/blink/renderer/platform/scheduler/main_thread/main_thread.h"

#include <stddef.h>
#include <memory>

#include "base/location.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
#include "base/test/simple_test_tick_clock.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/testing/scoped_scheduler_overrider.h"

namespace blink {
namespace scheduler {
// To avoid symbol collisions in jumbo builds.
namespace main_thread_unittest {

const int kWorkBatchSize = 2;

class MockTask {
 public:
  MOCK_METHOD0(Run, void());
};

class MockTaskObserver : public Thread::TaskObserver {
 public:
  MOCK_METHOD0(WillProcessTask, void());
  MOCK_METHOD0(DidProcessTask, void());
};

class MainThreadTest : public testing::Test {
 public:
  MainThreadTest() = default;

  void SetUp() override {
    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
    scheduler_.reset(new MainThreadSchedulerImpl(
        base::sequence_manager::SequenceManagerForTest::Create(
            &message_loop_, message_loop_.task_runner(), &clock_),
        base::nullopt));
    scheduler_overrider_ =
        std::make_unique<ScopedSchedulerOverrider>(scheduler_.get());
    thread_ = Thread::Current();
  }

  ~MainThreadTest() override = default;

  void SetWorkBatchSizeForTesting(int work_batch_size) {
    scheduler_->GetSchedulerHelperForTesting()->SetWorkBatchSizeForTesting(
        work_batch_size);
  }

  void TearDown() override { scheduler_->Shutdown(); }

 protected:
  base::MessageLoop message_loop_;
  base::SimpleTestTickClock clock_;
  std::unique_ptr<MainThreadSchedulerImpl> scheduler_;
  std::unique_ptr<ScopedSchedulerOverrider> scheduler_overrider_;
  Thread* thread_;

  DISALLOW_COPY_AND_ASSIGN(MainThreadTest);
};

TEST_F(MainThreadTest, TestTaskObserver) {
  MockTaskObserver observer;
  thread_->AddTaskObserver(&observer);
  MockTask task;

  {
    testing::InSequence sequence;
    EXPECT_CALL(observer, WillProcessTask());
    EXPECT_CALL(task, Run());
    EXPECT_CALL(observer, DidProcessTask());
  }

  message_loop_.task_runner()->PostTask(
      FROM_HERE, WTF::Bind(&MockTask::Run, WTF::Unretained(&task)));
  base::RunLoop().RunUntilIdle();
  thread_->RemoveTaskObserver(&observer);
}

TEST_F(MainThreadTest, TestWorkBatchWithOneTask) {
  MockTaskObserver observer;
  thread_->AddTaskObserver(&observer);
  MockTask task;

  SetWorkBatchSizeForTesting(kWorkBatchSize);
  {
    testing::InSequence sequence;
    EXPECT_CALL(observer, WillProcessTask());
    EXPECT_CALL(task, Run());
    EXPECT_CALL(observer, DidProcessTask());
  }

  message_loop_.task_runner()->PostTask(
      FROM_HERE, WTF::Bind(&MockTask::Run, WTF::Unretained(&task)));
  base::RunLoop().RunUntilIdle();
  thread_->RemoveTaskObserver(&observer);
}

TEST_F(MainThreadTest, TestWorkBatchWithTwoTasks) {
  MockTaskObserver observer;
  thread_->AddTaskObserver(&observer);
  MockTask task1;
  MockTask task2;

  SetWorkBatchSizeForTesting(kWorkBatchSize);
  {
    testing::InSequence sequence;
    EXPECT_CALL(observer, WillProcessTask());
    EXPECT_CALL(task1, Run());
    EXPECT_CALL(observer, DidProcessTask());

    EXPECT_CALL(observer, WillProcessTask());
    EXPECT_CALL(task2, Run());
    EXPECT_CALL(observer, DidProcessTask());
  }

  message_loop_.task_runner()->PostTask(
      FROM_HERE, WTF::Bind(&MockTask::Run, WTF::Unretained(&task1)));
  message_loop_.task_runner()->PostTask(
      FROM_HERE, WTF::Bind(&MockTask::Run, WTF::Unretained(&task2)));
  base::RunLoop().RunUntilIdle();
  thread_->RemoveTaskObserver(&observer);
}

TEST_F(MainThreadTest, TestWorkBatchWithThreeTasks) {
  MockTaskObserver observer;
  thread_->AddTaskObserver(&observer);
  MockTask task1;
  MockTask task2;
  MockTask task3;

  SetWorkBatchSizeForTesting(kWorkBatchSize);
  {
    testing::InSequence sequence;
    EXPECT_CALL(observer, WillProcessTask());
    EXPECT_CALL(task1, Run());
    EXPECT_CALL(observer, DidProcessTask());

    EXPECT_CALL(observer, WillProcessTask());
    EXPECT_CALL(task2, Run());
    EXPECT_CALL(observer, DidProcessTask());

    EXPECT_CALL(observer, WillProcessTask());
    EXPECT_CALL(task3, Run());
    EXPECT_CALL(observer, DidProcessTask());
  }

  message_loop_.task_runner()->PostTask(
      FROM_HERE, WTF::Bind(&MockTask::Run, WTF::Unretained(&task1)));
  message_loop_.task_runner()->PostTask(
      FROM_HERE, WTF::Bind(&MockTask::Run, WTF::Unretained(&task2)));
  message_loop_.task_runner()->PostTask(
      FROM_HERE, WTF::Bind(&MockTask::Run, WTF::Unretained(&task3)));
  base::RunLoop().RunUntilIdle();
  thread_->RemoveTaskObserver(&observer);
}

void EnterRunLoop(base::MessageLoop* message_loop, Thread* thread) {
  // Note: blink::Threads do not support nested run loops, which is why we use a
  // run loop directly.
  base::RunLoop run_loop;
  message_loop->task_runner()->PostTask(
      FROM_HERE, WTF::Bind(&base::RunLoop::Quit, WTF::Unretained(&run_loop)));
  message_loop->SetNestableTasksAllowed(true);
  run_loop.Run();
}

TEST_F(MainThreadTest, TestNestedRunLoop) {
  MockTaskObserver observer;
  thread_->AddTaskObserver(&observer);

  {
    testing::InSequence sequence;

    // One callback for EnterRunLoop.
    EXPECT_CALL(observer, WillProcessTask());

    // A pair for ExitRunLoopTask.
    EXPECT_CALL(observer, WillProcessTask());
    EXPECT_CALL(observer, DidProcessTask());

    // A final callback for EnterRunLoop.
    EXPECT_CALL(observer, DidProcessTask());
  }

  message_loop_.task_runner()->PostTask(
      FROM_HERE, base::BindOnce(&EnterRunLoop, base::Unretained(&message_loop_),
                                base::Unretained(thread_)));
  base::RunLoop().RunUntilIdle();
  thread_->RemoveTaskObserver(&observer);
}

}  // namespace main_thread_unittest
}  // namespace scheduler
}  // namespace blink
