// Copyright 2020 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/bind_post_task_forward.h"

#include "base/bind.h"
#include "base/callback.h"
#include "base/sequence_checker_impl.h"
#include "base/task/sequenced_task_runner_forward.h"
#include "base/test/task_environment.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace {

void SetBool(bool* variable, bool value) {
  *variable = value;
}

void SetInt(int* variable, int value) {
  *variable = value;
}

void SetIntFromUniquePtr(int* variable, std::unique_ptr<int> value) {
  *variable = *value;
}

int Multiply(int value) {
  return value * 5;
}

void ClearReference(OnceClosure callback) {}

class SequenceRestrictionChecker {
 public:
  explicit SequenceRestrictionChecker(bool& set_on_destroy)
      : set_on_destroy_(set_on_destroy) {}

  ~SequenceRestrictionChecker() {
    EXPECT_TRUE(checker_.CalledOnValidSequence());
    set_on_destroy_ = true;
  }

  void Run() { EXPECT_TRUE(checker_.CalledOnValidSequence()); }

 private:
  SequenceCheckerImpl checker_;
  bool& set_on_destroy_;
};

}  // namespace

class BindPostTaskTest : public testing::Test {
 protected:
  test::SingleThreadTaskEnvironment task_environment_;
  scoped_refptr<SequencedTaskRunner> task_runner_ =
      SequencedTaskRunnerHandle::Get();
};

TEST_F(BindPostTaskTest, OnceClosure) {
  bool val = false;
  OnceClosure cb = BindOnce(&SetBool, &val, true);
  OnceClosure post_cb = BindPostTask(task_runner_, std::move(cb));

  std::move(post_cb).Run();
  EXPECT_FALSE(val);

  RunLoop().RunUntilIdle();
  EXPECT_TRUE(val);
}

TEST_F(BindPostTaskTest, OnceCallback) {
  OnceCallback<void(bool*, bool)> cb = BindOnce(&SetBool);
  OnceCallback<void(bool*, bool)> post_cb =
      BindPostTask(task_runner_, std::move(cb));

  bool val = false;
  std::move(post_cb).Run(&val, true);
  EXPECT_FALSE(val);

  RunLoop().RunUntilIdle();
  EXPECT_TRUE(val);
}

TEST_F(BindPostTaskTest, OnceWithBoundMoveOnlyArg) {
  int val = 0;
  OnceClosure cb =
      BindOnce(&SetIntFromUniquePtr, &val, std::make_unique<int>(10));
  OnceClosure post_cb = BindPostTask(task_runner_, std::move(cb));

  std::move(post_cb).Run();
  EXPECT_EQ(val, 0);

  RunLoop().RunUntilIdle();
  EXPECT_EQ(val, 10);
}

TEST_F(BindPostTaskTest, OnceWithUnboundMoveOnlyArg) {
  int val = 0;
  OnceCallback<void(std::unique_ptr<int>)> cb =
      BindOnce(&SetIntFromUniquePtr, &val);
  OnceCallback<void(std::unique_ptr<int>)> post_cb =
      BindPostTask(task_runner_, std::move(cb));

  std::move(post_cb).Run(std::make_unique<int>(10));
  EXPECT_EQ(val, 0);

  RunLoop().RunUntilIdle();
  EXPECT_EQ(val, 10);
}

TEST_F(BindPostTaskTest, OnceWithIgnoreResult) {
  OnceCallback<void(int)> post_cb =
      BindPostTask(task_runner_, BindOnce(IgnoreResult(&Multiply)));
  std::move(post_cb).Run(1);
  RunLoop().RunUntilIdle();
}

TEST_F(BindPostTaskTest, OnceThen) {
  int value = 0;

  // Multiply() returns an int and SetInt() takes an int as a parameter.
  OnceClosure then_cb =
      BindOnce(&Multiply, 5)
          .Then(BindPostTask(task_runner_, BindOnce(&SetInt, &value)));

  std::move(then_cb).Run();
  EXPECT_EQ(value, 0);
  RunLoop().RunUntilIdle();
  EXPECT_EQ(value, 25);
}

// Ensure that the input callback is run/destroyed on the correct thread even if
// the callback returned from BindPostTask() is run on a different thread.
TEST_F(BindPostTaskTest, OnceRunDestroyedOnBound) {
  Thread target_thread("testing");
  ASSERT_TRUE(target_thread.Start());

  // SequenceRestrictionChecker checks it's creation, Run() and deletion all
  // happen on the main thread.
  bool destroyed = false;
  auto checker = std::make_unique<SequenceRestrictionChecker>(destroyed);

  // `checker` is owned by `cb` which is wrapped in `post_cb`. `post_cb` is run
  // on a different thread which triggers a PostTask() back to the test main
  // thread to invoke `cb` which runs SequenceRestrictionChecker::Run(). After
  // `cb` has been invoked `checker` is destroyed along with the BindState.
  OnceClosure cb =
      BindOnce(&SequenceRestrictionChecker::Run, std::move(checker));
  OnceClosure post_cb = BindPostTask(task_runner_, std::move(cb));
  target_thread.task_runner()->PostTask(FROM_HERE, std::move(post_cb));

  target_thread.FlushForTesting();
  EXPECT_FALSE(destroyed);
  RunLoop().RunUntilIdle();
  EXPECT_TRUE(destroyed);
}

// Ensure that the input callback is destroyed on the correct thread even if the
// callback returned from BindPostTask() is destroyed without being run on a
// different thread.
TEST_F(BindPostTaskTest, OnceNotRunDestroyedOnBound) {
  Thread target_thread("testing");
  ASSERT_TRUE(target_thread.Start());

  // SequenceRestrictionChecker checks it's creation and deletion all happen on
  // the test main thread.
  bool destroyed = false;
  auto checker = std::make_unique<SequenceRestrictionChecker>(destroyed);

  // `checker` is owned by `cb` which is wrapped in `post_cb`. `post_cb` is
  // deleted on a different thread which triggers a PostTask() back to the test
  // main thread to destroy `cb` and `checker`.
  OnceClosure cb =
      BindOnce(&SequenceRestrictionChecker::Run, std::move(checker));
  OnceClosure post_cb = BindPostTask(task_runner_, std::move(cb));
  target_thread.task_runner()->PostTask(
      FROM_HERE, BindOnce(&ClearReference, std::move(post_cb)));

  target_thread.FlushForTesting();
  EXPECT_FALSE(destroyed);
  RunLoop().RunUntilIdle();
  EXPECT_TRUE(destroyed);
}

TEST_F(BindPostTaskTest, RepeatingClosure) {
  bool val = false;
  RepeatingClosure cb = BindRepeating(&SetBool, &val, true);
  RepeatingClosure post_cb = BindPostTask(task_runner_, std::move(cb));

  post_cb.Run();
  EXPECT_FALSE(val);

  RunLoop().RunUntilIdle();
  EXPECT_TRUE(val);

  val = false;
  post_cb.Run();
  EXPECT_FALSE(val);

  RunLoop().RunUntilIdle();
  EXPECT_TRUE(val);
}

TEST_F(BindPostTaskTest, RepeatingCallback) {
  RepeatingCallback<void(bool*, bool)> cb = BindRepeating(&SetBool);
  RepeatingCallback<void(bool*, bool)> post_cb =
      BindPostTask(task_runner_, std::move(cb));

  bool val = false;
  post_cb.Run(&val, true);
  EXPECT_FALSE(val);

  RunLoop().RunUntilIdle();
  EXPECT_TRUE(val);

  post_cb.Run(&val, false);
  EXPECT_TRUE(val);

  RunLoop().RunUntilIdle();
  EXPECT_FALSE(val);
}

TEST_F(BindPostTaskTest, RepeatingWithUnboundMoveOnlyArg) {
  int val = 0;
  RepeatingCallback<void(std::unique_ptr<int>)> cb =
      BindRepeating(&SetIntFromUniquePtr, &val);
  RepeatingCallback<void(std::unique_ptr<int>)> post_cb =
      BindPostTask(task_runner_, std::move(cb));

  post_cb.Run(std::make_unique<int>(10));
  EXPECT_EQ(val, 0);

  RunLoop().RunUntilIdle();
  EXPECT_EQ(val, 10);

  post_cb.Run(std::make_unique<int>(20));
  EXPECT_EQ(val, 10);

  RunLoop().RunUntilIdle();
  EXPECT_EQ(val, 20);
}

TEST_F(BindPostTaskTest, RepeatingWithIgnoreResult) {
  RepeatingCallback<void(int)> post_cb =
      BindPostTask(task_runner_, BindRepeating(IgnoreResult(&Multiply)));
  std::move(post_cb).Run(1);
  RunLoop().RunUntilIdle();
}

TEST_F(BindPostTaskTest, RepeatingThen) {
  int value = 0;

  // Multiply() returns an int and SetInt() takes an int as a parameter.
  RepeatingCallback<void(int)> then_cb = BindRepeating(&Multiply).Then(
      BindPostTask(task_runner_, BindRepeating(&SetInt, &value)));

  then_cb.Run(5);
  EXPECT_EQ(value, 0);
  RunLoop().RunUntilIdle();
  EXPECT_EQ(value, 25);

  then_cb.Run(10);
  EXPECT_EQ(value, 25);
  RunLoop().RunUntilIdle();
  EXPECT_EQ(value, 50);
}

// Ensure that the input callback is run/destroyed on the correct thread even if
// the callback returned from BindPostTask() is run on a different thread.
TEST_F(BindPostTaskTest, RepeatingRunDestroyedOnBound) {
  Thread target_thread("testing");
  ASSERT_TRUE(target_thread.Start());

  // SequenceRestrictionChecker checks it's creation, Run() and deletion all
  // happen on the main thread.
  bool destroyed = false;
  auto checker = std::make_unique<SequenceRestrictionChecker>(destroyed);

  // `checker` is owned by `cb` which is wrapped in `post_cb`. `post_cb` is run
  // on a different thread which triggers a PostTask() back to the test main
  // thread to invoke `cb` which runs SequenceRestrictionChecker::Run(). After
  // `cb` has been invoked `checker` is destroyed along with the BindState.
  RepeatingClosure cb =
      BindRepeating(&SequenceRestrictionChecker::Run, std::move(checker));
  RepeatingClosure post_cb = BindPostTask(task_runner_, std::move(cb));
  target_thread.task_runner()->PostTask(FROM_HERE, std::move(post_cb));

  target_thread.FlushForTesting();
  EXPECT_FALSE(destroyed);
  RunLoop().RunUntilIdle();
  EXPECT_TRUE(destroyed);
}

// Ensure that the input callback is destroyed on the correct thread even if the
// callback returned from BindPostTask() is destroyed without being run on a
// different thread.
TEST_F(BindPostTaskTest, RepeatingNotRunDestroyedOnBound) {
  Thread target_thread("testing");
  ASSERT_TRUE(target_thread.Start());

  // SequenceRestrictionChecker checks it's creation and deletion all happen on
  // the test main thread.
  bool destroyed = false;
  auto checker = std::make_unique<SequenceRestrictionChecker>(destroyed);

  // `checker` is owned by `cb` which is wrapped in `post_cb`. `post_cb` is
  // deleted on a different thread which triggers a PostTask() back to the test
  // main thread to destroy `cb` and `checker`.
  RepeatingClosure cb =
      BindRepeating(&SequenceRestrictionChecker::Run, std::move(checker));
  RepeatingClosure post_cb = BindPostTask(task_runner_, std::move(cb));
  target_thread.task_runner()->PostTask(
      FROM_HERE, BindRepeating(&ClearReference, std::move(post_cb)));

  target_thread.FlushForTesting();
  EXPECT_FALSE(destroyed);
  RunLoop().RunUntilIdle();
  EXPECT_TRUE(destroyed);
}

}  // namespace base
