// 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 "chrome/browser/after_startup_task_utils.h"

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/sequenced_task_runner.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "base/task_runner_util.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

class WrappedTaskRunner : public base::SequencedTaskRunner {
 public:
  explicit WrappedTaskRunner(scoped_refptr<SequencedTaskRunner> real_runner)
      : real_task_runner_(std::move(real_runner)) {}

  bool PostDelayedTask(const base::Location& from_here,
                       base::OnceClosure task,
                       base::TimeDelta delay) override {
    ++posted_task_count_;
    return real_task_runner_->PostDelayedTask(
        from_here,
        base::BindOnce(&WrappedTaskRunner::RunWrappedTask, this,
                       std::move(task)),
        base::TimeDelta());  // Squash all delays so our tests complete asap.
  }

  bool PostNonNestableDelayedTask(const base::Location& from_here,
                                  base::OnceClosure task,
                                  base::TimeDelta delay) override {
    // Not implemented.
    NOTREACHED();
    return false;
  }

  bool RunsTasksInCurrentSequence() const override {
    return real_task_runner_->RunsTasksInCurrentSequence();
  }

  base::SequencedTaskRunner* real_runner() const {
    return real_task_runner_.get();
  }

  int total_task_count() const { return posted_task_count_ + ran_task_count_; }
  int posted_task_count() const { return posted_task_count_; }
  int ran_task_count() const { return ran_task_count_; }

  void reset_task_counts() {
    posted_task_count_ = 0;
    ran_task_count_ = 0;
  }

 private:
  ~WrappedTaskRunner() override {}

  void RunWrappedTask(base::OnceClosure task) {
    ++ran_task_count_;
    std::move(task).Run();
  }

  scoped_refptr<base::SequencedTaskRunner> real_task_runner_;
  int posted_task_count_ = 0;
  int ran_task_count_ = 0;
};

}  // namespace

class AfterStartupTaskTest : public testing::Test {
 public:
  AfterStartupTaskTest() {
    ui_thread_ = base::MakeRefCounted<WrappedTaskRunner>(
        content::GetUIThreadTaskRunner({}));
    background_sequence_ = base::MakeRefCounted<WrappedTaskRunner>(
        base::ThreadPool::CreateSequencedTaskRunner({}));
    AfterStartupTaskUtils::UnsafeResetForTesting();
  }

  // Hop to the background sequence and call IsBrowserStartupComplete.
  bool GetIsBrowserStartupCompleteFromBackgroundSequence() {
    base::RunLoop run_loop;
    bool is_complete;
    base::PostTaskAndReplyWithResult(
        background_sequence_->real_runner(), FROM_HERE,
        base::BindOnce(&AfterStartupTaskUtils::IsBrowserStartupComplete),
        base::BindOnce(&AfterStartupTaskTest::GotIsOnBrowserStartupComplete,
                       &run_loop, &is_complete));
    run_loop.Run();
    return is_complete;
  }

  // Hop to the background sequence and call PostAfterStartupTask.
  void PostAfterStartupTaskFromBackgroundSequence(
      const base::Location& from_here,
      scoped_refptr<base::SequencedTaskRunner> task_runner,
      base::OnceClosure task) {
    base::RunLoop run_loop;
    background_sequence_->real_runner()->PostTaskAndReply(
        FROM_HERE,
        base::BindOnce(&AfterStartupTaskUtils::PostTask, from_here,
                       std::move(task_runner), std::move(task)),
        base::BindOnce(&base::RunLoop::Quit, base::Unretained(&run_loop)));
    run_loop.Run();
  }

  // Make sure all tasks posted to the background sequence get run.
  void FlushBackgroundSequence() {
    base::RunLoop run_loop;
    background_sequence_->real_runner()->PostTaskAndReply(
        FROM_HERE, base::DoNothing(),
        base::BindOnce(&base::RunLoop::Quit, base::Unretained(&run_loop)));
    run_loop.Run();
  }

  static void VerifyExpectedSequence(base::SequencedTaskRunner* task_runner) {
    EXPECT_TRUE(task_runner->RunsTasksInCurrentSequence());
  }

 protected:
  scoped_refptr<WrappedTaskRunner> ui_thread_;
  scoped_refptr<WrappedTaskRunner> background_sequence_;

 private:
  static void GotIsOnBrowserStartupComplete(base::RunLoop* loop,
                                            bool* out,
                                            bool is_complete) {
    *out = is_complete;
    loop->Quit();
  }

  content::BrowserTaskEnvironment task_environment_;
};

TEST_F(AfterStartupTaskTest, IsStartupComplete) {
  // Check IsBrowserStartupComplete on a background sequence first to
  // verify that it does not allocate the underlying flag on that sequence.
  // That allocation sequence correctness part of this test relies on
  // the DCHECK in CancellationFlag::Set().
  EXPECT_FALSE(GetIsBrowserStartupCompleteFromBackgroundSequence());
  EXPECT_FALSE(AfterStartupTaskUtils::IsBrowserStartupComplete());
  AfterStartupTaskUtils::SetBrowserStartupIsCompleteForTesting();
  EXPECT_TRUE(AfterStartupTaskUtils::IsBrowserStartupComplete());
  EXPECT_TRUE(GetIsBrowserStartupCompleteFromBackgroundSequence());
}

TEST_F(AfterStartupTaskTest, PostTask) {
  // Nothing should be posted prior to startup completion.
  EXPECT_FALSE(AfterStartupTaskUtils::IsBrowserStartupComplete());
  AfterStartupTaskUtils::PostTask(
      FROM_HERE, ui_thread_,
      base::BindOnce(&AfterStartupTaskTest::VerifyExpectedSequence,
                     base::RetainedRef(ui_thread_)));
  AfterStartupTaskUtils::PostTask(
      FROM_HERE, background_sequence_,
      base::BindOnce(&AfterStartupTaskTest::VerifyExpectedSequence,
                     base::RetainedRef(background_sequence_)));
  PostAfterStartupTaskFromBackgroundSequence(
      FROM_HERE, ui_thread_,
      base::BindOnce(&AfterStartupTaskTest::VerifyExpectedSequence,
                     base::RetainedRef(ui_thread_)));
  PostAfterStartupTaskFromBackgroundSequence(
      FROM_HERE, background_sequence_,
      base::BindOnce(&AfterStartupTaskTest::VerifyExpectedSequence,
                     base::RetainedRef(background_sequence_)));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, background_sequence_->total_task_count() +
                   ui_thread_->total_task_count());

  // Queued tasks should be posted upon setting the flag.
  AfterStartupTaskUtils::SetBrowserStartupIsCompleteForTesting();
  EXPECT_EQ(2, background_sequence_->posted_task_count());
  EXPECT_EQ(2, ui_thread_->posted_task_count());
  FlushBackgroundSequence();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2, background_sequence_->ran_task_count());
  EXPECT_EQ(2, ui_thread_->ran_task_count());

  background_sequence_->reset_task_counts();
  ui_thread_->reset_task_counts();
  EXPECT_EQ(0, background_sequence_->total_task_count() +
                   ui_thread_->total_task_count());

  // Tasks posted after startup should get posted immediately.
  AfterStartupTaskUtils::PostTask(FROM_HERE, ui_thread_, base::DoNothing());
  AfterStartupTaskUtils::PostTask(FROM_HERE, background_sequence_,
                                  base::DoNothing());
  EXPECT_EQ(1, background_sequence_->posted_task_count());
  EXPECT_EQ(1, ui_thread_->posted_task_count());
  PostAfterStartupTaskFromBackgroundSequence(FROM_HERE, ui_thread_,
                                             base::DoNothing());
  PostAfterStartupTaskFromBackgroundSequence(FROM_HERE, background_sequence_,
                                             base::DoNothing());
  EXPECT_EQ(2, background_sequence_->posted_task_count());
  EXPECT_EQ(2, ui_thread_->posted_task_count());
  FlushBackgroundSequence();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2, background_sequence_->ran_task_count());
  EXPECT_EQ(2, ui_thread_->ran_task_count());
}
