// 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 "base/macros.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace internal {

namespace {

class TaskSchedulerSequenceTest : public testing::Test {
 public:
  TaskSchedulerSequenceTest()
      : task_a_owned_(
            new Task(FROM_HERE,
                     Closure(),
                     TaskTraits().WithPriority(TaskPriority::BACKGROUND),
                     TimeDelta())),
        task_b_owned_(
            new Task(FROM_HERE,
                     Closure(),
                     TaskTraits().WithPriority(TaskPriority::USER_VISIBLE),
                     TimeDelta())),
        task_c_owned_(
            new Task(FROM_HERE,
                     Closure(),
                     TaskTraits().WithPriority(TaskPriority::USER_BLOCKING),
                     TimeDelta())),
        task_d_owned_(
            new Task(FROM_HERE,
                     Closure(),
                     TaskTraits().WithPriority(TaskPriority::USER_BLOCKING),
                     TimeDelta())),
        task_e_owned_(
            new Task(FROM_HERE,
                     Closure(),
                     TaskTraits().WithPriority(TaskPriority::BACKGROUND),
                     TimeDelta())),
        task_a_(task_a_owned_.get()),
        task_b_(task_b_owned_.get()),
        task_c_(task_c_owned_.get()),
        task_d_(task_d_owned_.get()),
        task_e_(task_e_owned_.get()) {}

 protected:
  // Tasks to be handed off to a Sequence for testing.
  std::unique_ptr<Task> task_a_owned_;
  std::unique_ptr<Task> task_b_owned_;
  std::unique_ptr<Task> task_c_owned_;
  std::unique_ptr<Task> task_d_owned_;
  std::unique_ptr<Task> task_e_owned_;

  // Raw pointers to those same tasks for verification. This is needed because
  // the scoped_ptrs above no longer point to the tasks once they have been
  // moved into a Sequence.
  const Task* task_a_;
  const Task* task_b_;
  const Task* task_c_;
  const Task* task_d_;
  const Task* task_e_;

 private:
  DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSequenceTest);
};

}  // namespace

TEST_F(TaskSchedulerSequenceTest, PushPopPeek) {
  scoped_refptr<Sequence> sequence(new Sequence);

  // Push task A in the sequence. Its sequenced time should be updated and it
  // should be in front of the sequence.
  EXPECT_TRUE(sequence->PushTask(std::move(task_a_owned_)));
  EXPECT_FALSE(task_a_->sequenced_time.is_null());
  EXPECT_EQ(task_a_, sequence->PeekTask());

  // Push task B, C and D in the sequence. Their sequenced time should be
  // updated and task A should always remain in front of the sequence.
  EXPECT_FALSE(sequence->PushTask(std::move(task_b_owned_)));
  EXPECT_FALSE(task_b_->sequenced_time.is_null());
  EXPECT_EQ(task_a_, sequence->PeekTask());

  EXPECT_FALSE(sequence->PushTask(std::move(task_c_owned_)));
  EXPECT_FALSE(task_c_->sequenced_time.is_null());
  EXPECT_EQ(task_a_, sequence->PeekTask());

  EXPECT_FALSE(sequence->PushTask(std::move(task_d_owned_)));
  EXPECT_FALSE(task_d_->sequenced_time.is_null());
  EXPECT_EQ(task_a_, sequence->PeekTask());

  // Pop task A. Task B should now be in front.
  EXPECT_FALSE(sequence->PopTask());
  EXPECT_EQ(task_b_, sequence->PeekTask());

  // Pop task B. Task C should now be in front.
  EXPECT_FALSE(sequence->PopTask());
  EXPECT_EQ(task_c_, sequence->PeekTask());

  // Pop task C. Task D should now be in front.
  EXPECT_FALSE(sequence->PopTask());
  EXPECT_EQ(task_d_, sequence->PeekTask());

  // Push task E in the sequence. Its sequenced time should be updated and
  // task D should remain in front.
  EXPECT_FALSE(sequence->PushTask(std::move(task_e_owned_)));
  EXPECT_FALSE(task_e_->sequenced_time.is_null());
  EXPECT_EQ(task_d_, sequence->PeekTask());

  // Pop task D. Task E should now be in front.
  EXPECT_FALSE(sequence->PopTask());
  EXPECT_EQ(task_e_, sequence->PeekTask());

  // Pop task E. The sequence should now be empty.
  EXPECT_TRUE(sequence->PopTask());
  EXPECT_EQ(nullptr, sequence->PeekTask());
}

TEST_F(TaskSchedulerSequenceTest, GetSortKey) {
  scoped_refptr<Sequence> sequence(new Sequence);

  // Push task A in the sequence. The highest priority is from task A
  // (BACKGROUND). Task A is in front of the sequence.
  sequence->PushTask(std::move(task_a_owned_));
  EXPECT_EQ(SequenceSortKey(TaskPriority::BACKGROUND, task_a_->sequenced_time),
            sequence->GetSortKey());

  // Push task B in the sequence. The highest priority is from task B
  // (USER_VISIBLE). Task A is still in front of the sequence.
  sequence->PushTask(std::move(task_b_owned_));
  EXPECT_EQ(
      SequenceSortKey(TaskPriority::USER_VISIBLE, task_a_->sequenced_time),
      sequence->GetSortKey());

  // Push task C in the sequence. The highest priority is from task C
  // (USER_BLOCKING). Task A is still in front of the sequence.
  sequence->PushTask(std::move(task_c_owned_));
  EXPECT_EQ(
      SequenceSortKey(TaskPriority::USER_BLOCKING, task_a_->sequenced_time),
      sequence->GetSortKey());

  // Push task D in the sequence. The highest priority is from tasks C/D
  // (USER_BLOCKING). Task A is still in front of the sequence.
  sequence->PushTask(std::move(task_d_owned_));
  EXPECT_EQ(
      SequenceSortKey(TaskPriority::USER_BLOCKING, task_a_->sequenced_time),
      sequence->GetSortKey());

  // Pop task A. The highest priority is still USER_BLOCKING. The task in front
  // of the sequence is now task B.
  sequence->PopTask();
  EXPECT_EQ(
      SequenceSortKey(TaskPriority::USER_BLOCKING, task_b_->sequenced_time),
      sequence->GetSortKey());

  // Pop task B. The highest priority is still USER_BLOCKING. The task in front
  // of the sequence is now task C.
  sequence->PopTask();
  EXPECT_EQ(
      SequenceSortKey(TaskPriority::USER_BLOCKING, task_c_->sequenced_time),
      sequence->GetSortKey());

  // Pop task C. The highest priority is still USER_BLOCKING. The task in front
  // of the sequence is now task D.
  sequence->PopTask();
  EXPECT_EQ(
      SequenceSortKey(TaskPriority::USER_BLOCKING, task_d_->sequenced_time),
      sequence->GetSortKey());

  // Push task E in the sequence. The highest priority is still USER_BLOCKING.
  // The task in front of the sequence is still task D.
  sequence->PushTask(std::move(task_e_owned_));
  EXPECT_EQ(
      SequenceSortKey(TaskPriority::USER_BLOCKING, task_d_->sequenced_time),
      sequence->GetSortKey());

  // Pop task D. The highest priority is now from task E (BACKGROUND). The
  // task in front of the sequence is now task E.
  sequence->PopTask();
  EXPECT_EQ(SequenceSortKey(TaskPriority::BACKGROUND, task_e_->sequenced_time),
            sequence->GetSortKey());
}

}  // namespace internal
}  // namespace base
