// Copyright (c) 2013 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/deferred_sequenced_task_runner.h"

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/threading/non_thread_safe.h"
#include "base/threading/thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

class DeferredSequencedTaskRunnerTest : public testing::Test,
                                        public base::NonThreadSafe {
 public:
  class ExecuteTaskOnDestructor :
      public base::RefCounted<ExecuteTaskOnDestructor> {
   public:
    ExecuteTaskOnDestructor(
        DeferredSequencedTaskRunnerTest* executor,
        int task_id)
        : executor_(executor),
          task_id_(task_id) {
    }
  private:
    friend class base::RefCounted<ExecuteTaskOnDestructor>;
    virtual ~ExecuteTaskOnDestructor() {
      executor_->ExecuteTask(task_id_);
    }
    DeferredSequencedTaskRunnerTest* executor_;
    int task_id_;
  };

  void ExecuteTask(int task_id) {
    base::AutoLock lock(lock_);
    executed_task_ids_.push_back(task_id);
  }

  void PostExecuteTask(int task_id) {
    runner_->PostTask(FROM_HERE,
                      base::Bind(&DeferredSequencedTaskRunnerTest::ExecuteTask,
                                 base::Unretained(this),
                                 task_id));
  }

  void StartRunner() {
    runner_->Start();
  }

  void DoNothing(ExecuteTaskOnDestructor* object) {
  }

 protected:
  DeferredSequencedTaskRunnerTest() :
      loop_(),
      runner_(
          new base::DeferredSequencedTaskRunner(loop_.message_loop_proxy())) {
  }

  base::MessageLoop loop_;
  scoped_refptr<base::DeferredSequencedTaskRunner> runner_;
  mutable base::Lock lock_;
  std::vector<int> executed_task_ids_;
};

TEST_F(DeferredSequencedTaskRunnerTest, Stopped) {
  PostExecuteTask(1);
  loop_.RunUntilIdle();
  EXPECT_THAT(executed_task_ids_, testing::ElementsAre());
}

TEST_F(DeferredSequencedTaskRunnerTest, Start) {
  StartRunner();
  PostExecuteTask(1);
  loop_.RunUntilIdle();
  EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1));
}

TEST_F(DeferredSequencedTaskRunnerTest, StartWithMultipleElements) {
  StartRunner();
  for (int i = 1; i < 5; ++i)
    PostExecuteTask(i);

  loop_.RunUntilIdle();
  EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1, 2, 3, 4));
}

TEST_F(DeferredSequencedTaskRunnerTest, DeferredStart) {
  PostExecuteTask(1);
  loop_.RunUntilIdle();
  EXPECT_THAT(executed_task_ids_, testing::ElementsAre());

  StartRunner();
  loop_.RunUntilIdle();
  EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1));

  PostExecuteTask(2);
  loop_.RunUntilIdle();
  EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1, 2));
}

TEST_F(DeferredSequencedTaskRunnerTest, DeferredStartWithMultipleElements) {
  for (int i = 1; i < 5; ++i)
    PostExecuteTask(i);
  loop_.RunUntilIdle();
  EXPECT_THAT(executed_task_ids_, testing::ElementsAre());

  StartRunner();
  for (int i = 5; i < 9; ++i)
    PostExecuteTask(i);
  loop_.RunUntilIdle();
  EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1, 2, 3, 4, 5, 6, 7, 8));
}

TEST_F(DeferredSequencedTaskRunnerTest, DeferredStartWithMultipleThreads) {
  {
    base::Thread thread1("DeferredSequencedTaskRunnerTestThread1");
    base::Thread thread2("DeferredSequencedTaskRunnerTestThread2");
    thread1.Start();
    thread2.Start();
    for (int i = 0; i < 5; ++i) {
      thread1.message_loop()->PostTask(
          FROM_HERE,
          base::Bind(&DeferredSequencedTaskRunnerTest::PostExecuteTask,
                     base::Unretained(this),
                     2 * i));
      thread2.message_loop()->PostTask(
          FROM_HERE,
          base::Bind(&DeferredSequencedTaskRunnerTest::PostExecuteTask,
                     base::Unretained(this),
                     2 * i + 1));
      if (i == 2) {
        thread1.message_loop()->PostTask(
            FROM_HERE,
            base::Bind(&DeferredSequencedTaskRunnerTest::StartRunner,
                       base::Unretained(this)));
      }
    }
  }

  loop_.RunUntilIdle();
  EXPECT_THAT(executed_task_ids_,
      testing::WhenSorted(testing::ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)));
}

TEST_F(DeferredSequencedTaskRunnerTest, ObjectDestructionOrder) {
  {
    base::Thread thread("DeferredSequencedTaskRunnerTestThread");
    thread.Start();
    runner_ =
        new base::DeferredSequencedTaskRunner(thread.message_loop_proxy());
    for (int i = 0; i < 5; ++i) {
      {
        // Use a block to ensure that no reference to |short_lived_object|
        // is kept on the main thread after it is posted to |runner_|.
        scoped_refptr<ExecuteTaskOnDestructor> short_lived_object =
            new ExecuteTaskOnDestructor(this, 2 * i);
        runner_->PostTask(
            FROM_HERE,
            base::Bind(&DeferredSequencedTaskRunnerTest::DoNothing,
                       base::Unretained(this),
                       short_lived_object));
      }
      // |short_lived_object| with id |2 * i| should be destroyed before the
      // task |2 * i + 1| is executed.
      PostExecuteTask(2 * i + 1);
    }
    StartRunner();
  }

  // All |short_lived_object| with id |2 * i| are destroyed before the task
  // |2 * i + 1| is executed.
  EXPECT_THAT(executed_task_ids_,
              testing::ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
}

}  // namespace
