// 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 "base/threading/sequenced_task_runner_handle.h"

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/sequence_checker_impl.h"
#include "base/sequenced_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/task_scheduler/post_task.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace {

class SequencedTaskRunnerHandleTest : public ::testing::Test {
 protected:
  // Verifies that the context it runs on has a SequencedTaskRunnerHandle
  // and that posting to it results in the posted task running in that same
  // context (sequence).
  static void VerifyCurrentSequencedTaskRunner() {
    ASSERT_TRUE(SequencedTaskRunnerHandle::IsSet());
    scoped_refptr<SequencedTaskRunner> task_runner =
        SequencedTaskRunnerHandle::Get();
    ASSERT_TRUE(task_runner);

    // Use SequenceCheckerImpl to make sure it's not a no-op in Release builds.
    std::unique_ptr<SequenceCheckerImpl> sequence_checker(
        new SequenceCheckerImpl);
    task_runner->PostTask(
        FROM_HERE,
        base::BindOnce(&SequencedTaskRunnerHandleTest::CheckValidSequence,
                       std::move(sequence_checker)));
  }

  static void CheckValidSequence(
      std::unique_ptr<SequenceCheckerImpl> sequence_checker) {
    EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
  }

  base::test::ScopedTaskEnvironment scoped_task_environment_;
};

TEST_F(SequencedTaskRunnerHandleTest, FromMessageLoop) {
  VerifyCurrentSequencedTaskRunner();
  RunLoop().RunUntilIdle();
}

TEST_F(SequencedTaskRunnerHandleTest, FromTaskSchedulerSequencedTask) {
  base::CreateSequencedTaskRunnerWithTraits({})->PostTask(
      FROM_HERE,
      base::BindOnce(
          &SequencedTaskRunnerHandleTest::VerifyCurrentSequencedTaskRunner));
  scoped_task_environment_.RunUntilIdle();
}

TEST_F(SequencedTaskRunnerHandleTest, NoHandleFromUnsequencedTask) {
  base::PostTask(FROM_HERE, base::BindOnce([]() {
                   EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet());
                 }));
  scoped_task_environment_.RunUntilIdle();
}

TEST(SequencedTaskRunnerHandleTestWithoutMessageLoop, FromHandleInScope) {
  scoped_refptr<SequencedTaskRunner> test_task_runner(new TestSimpleTaskRunner);
  EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet());
  EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet());
  {
    SequencedTaskRunnerHandle handle(test_task_runner);
    EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet());
    EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet());
    EXPECT_EQ(test_task_runner, SequencedTaskRunnerHandle::Get());
  }
  EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet());
  EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet());
}

}  // namespace
}  // namespace base
