// Copyright 2016 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_scheduler/sequence.h"

#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/test/gtest_util.h"
#include "base/time/time.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace internal {

namespace {

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

Task CreateTask(MockTask* mock_task) {
  return Task(FROM_HERE, BindOnce(&MockTask::Run, Unretained(mock_task)),
              {TaskPriority::BEST_EFFORT}, TimeDelta());
}

void ExpectMockTask(MockTask* mock_task, Task* task) {
  EXPECT_CALL(*mock_task, Run());
  std::move(task->task).Run();
  testing::Mock::VerifyAndClear(mock_task);
}

}  // namespace

TEST(TaskSchedulerSequenceTest, PushTakeRemove) {
  testing::StrictMock<MockTask> mock_task_a;
  testing::StrictMock<MockTask> mock_task_b;
  testing::StrictMock<MockTask> mock_task_c;
  testing::StrictMock<MockTask> mock_task_d;
  testing::StrictMock<MockTask> mock_task_e;

  scoped_refptr<Sequence> sequence = MakeRefCounted<Sequence>();

  // Push task A in the sequence. PushTask() should return true since it's the
  // first task->
  EXPECT_TRUE(sequence->PushTask(CreateTask(&mock_task_a)));

  // Push task B, C and D in the sequence. PushTask() should return false since
  // there is already a task in a sequence.
  EXPECT_FALSE(sequence->PushTask(CreateTask(&mock_task_b)));
  EXPECT_FALSE(sequence->PushTask(CreateTask(&mock_task_c)));
  EXPECT_FALSE(sequence->PushTask(CreateTask(&mock_task_d)));

  // Take the task in front of the sequence. It should be task A.
  Optional<Task> task = sequence->TakeTask();
  ExpectMockTask(&mock_task_a, &task.value());
  EXPECT_FALSE(task->sequenced_time.is_null());

  // Remove the empty slot. Task B should now be in front.
  EXPECT_FALSE(sequence->Pop());
  task = sequence->TakeTask();
  ExpectMockTask(&mock_task_b, &task.value());
  EXPECT_FALSE(task->sequenced_time.is_null());

  // Remove the empty slot. Task C should now be in front.
  EXPECT_FALSE(sequence->Pop());
  task = sequence->TakeTask();
  ExpectMockTask(&mock_task_c, &task.value());
  EXPECT_FALSE(task->sequenced_time.is_null());

  // Remove the empty slot.
  EXPECT_FALSE(sequence->Pop());

  // Push task E in the sequence.
  EXPECT_FALSE(sequence->PushTask(CreateTask(&mock_task_e)));

  // Task D should be in front.
  task = sequence->TakeTask();
  ExpectMockTask(&mock_task_d, &task.value());
  EXPECT_FALSE(task->sequenced_time.is_null());

  // Remove the empty slot. Task E should now be in front.
  EXPECT_FALSE(sequence->Pop());
  task = sequence->TakeTask();
  ExpectMockTask(&mock_task_e, &task.value());
  EXPECT_FALSE(task->sequenced_time.is_null());

  // Remove the empty slot. The sequence should now be empty.
  EXPECT_TRUE(sequence->Pop());
}

// Verifies the sort key of a sequence that contains one BEST_EFFORT task.
TEST(TaskSchedulerSequenceTest, GetSortKeyBackground) {
  // Create a sequence with a BEST_EFFORT task.
  Task background_task(FROM_HERE, DoNothing(), {TaskPriority::BEST_EFFORT},
                       TimeDelta());
  scoped_refptr<Sequence> background_sequence = MakeRefCounted<Sequence>();
  background_sequence->PushTask(std::move(background_task));

  // Get the sort key.
  const SequenceSortKey background_sort_key = background_sequence->GetSortKey();

  // Take the task from the sequence, so that its sequenced time is available
  // for the check below.
  auto take_background_task = background_sequence->TakeTask();

  // Verify the sort key.
  EXPECT_EQ(TaskPriority::BEST_EFFORT, background_sort_key.priority());
  EXPECT_EQ(take_background_task->sequenced_time,
            background_sort_key.next_task_sequenced_time());

  // Pop for correctness.
  background_sequence->Pop();
}

// Same as TaskSchedulerSequenceTest.GetSortKeyBackground, but with a
// USER_VISIBLE task.
TEST(TaskSchedulerSequenceTest, GetSortKeyForeground) {
  // Create a sequence with a USER_VISIBLE task.
  Task foreground_task(FROM_HERE, DoNothing(), {TaskPriority::USER_VISIBLE},
                       TimeDelta());
  scoped_refptr<Sequence> foreground_sequence = MakeRefCounted<Sequence>();
  foreground_sequence->PushTask(std::move(foreground_task));

  // Get the sort key.
  const SequenceSortKey foreground_sort_key = foreground_sequence->GetSortKey();

  // Take the task from the sequence, so that its sequenced time is available
  // for the check below.
  auto take_foreground_task = foreground_sequence->TakeTask();

  // Verify the sort key.
  EXPECT_EQ(TaskPriority::USER_VISIBLE, foreground_sort_key.priority());
  EXPECT_EQ(take_foreground_task->sequenced_time,
            foreground_sort_key.next_task_sequenced_time());

  // Pop for correctness.
  foreground_sequence->Pop();
}

// Verify that a DCHECK fires if Pop() is called on a sequence whose front slot
// isn't empty.
TEST(TaskSchedulerSequenceTest, PopNonEmptyFrontSlot) {
  scoped_refptr<Sequence> sequence = MakeRefCounted<Sequence>();
  sequence->PushTask(Task(FROM_HERE, DoNothing(), TaskTraits(), TimeDelta()));

  EXPECT_DCHECK_DEATH({ sequence->Pop(); });
}

// Verify that a DCHECK fires if TakeTask() is called on a sequence whose front
// slot is empty.
TEST(TaskSchedulerSequenceTest, TakeEmptyFrontSlot) {
  scoped_refptr<Sequence> sequence = MakeRefCounted<Sequence>();
  sequence->PushTask(Task(FROM_HERE, DoNothing(), TaskTraits(), TimeDelta()));

  EXPECT_TRUE(sequence->TakeTask());
  EXPECT_DCHECK_DEATH({ sequence->TakeTask(); });
}

// Verify that a DCHECK fires if TakeTask() is called on an empty sequence.
TEST(TaskSchedulerSequenceTest, TakeEmptySequence) {
  scoped_refptr<Sequence> sequence = MakeRefCounted<Sequence>();
  EXPECT_DCHECK_DEATH({ sequence->TakeTask(); });
}

}  // namespace internal
}  // namespace base
