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

#include <utility>

#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/test/test_mock_time_task_runner.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;

namespace base {
namespace internal {

namespace {

class PostTaskAndReplyTaskRunner : public internal::PostTaskAndReplyImpl {
 public:
  explicit PostTaskAndReplyTaskRunner(TaskRunner* destination)
      : destination_(destination) {}

 private:
  bool PostTask(const Location& from_here, OnceClosure task) override {
    return destination_->PostTask(from_here, std::move(task));
  }

  // Non-owning.
  TaskRunner* const destination_;
};

class ObjectToDelete : public RefCounted<ObjectToDelete> {
 public:
  // |delete_flag| is set to true when this object is deleted
  ObjectToDelete(bool* delete_flag) : delete_flag_(delete_flag) {
    EXPECT_FALSE(*delete_flag_);
  }

 private:
  friend class RefCounted<ObjectToDelete>;
  ~ObjectToDelete() { *delete_flag_ = true; }

  bool* const delete_flag_;

  DISALLOW_COPY_AND_ASSIGN(ObjectToDelete);
};

class MockObject {
 public:
  MockObject() = default;

  MOCK_METHOD1(Task, void(scoped_refptr<ObjectToDelete>));
  MOCK_METHOD1(Reply, void(scoped_refptr<ObjectToDelete>));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockObject);
};

class MockRunsTasksInCurrentSequenceTaskRunner : public TestMockTimeTaskRunner {
 public:
  MockRunsTasksInCurrentSequenceTaskRunner(
      TestMockTimeTaskRunner::Type type =
          TestMockTimeTaskRunner::Type::kStandalone)
      : TestMockTimeTaskRunner(type) {}

  void RunUntilIdleWithRunsTasksInCurrentSequence() {
    AutoReset<bool> reset(&runs_tasks_in_current_sequence_, true);
    RunUntilIdle();
  }

  void ClearPendingTasksWithRunsTasksInCurrentSequence() {
    AutoReset<bool> reset(&runs_tasks_in_current_sequence_, true);
    ClearPendingTasks();
  }

  // TestMockTimeTaskRunner:
  bool RunsTasksInCurrentSequence() const override {
    return runs_tasks_in_current_sequence_;
  }

 private:
  ~MockRunsTasksInCurrentSequenceTaskRunner() override = default;

  bool runs_tasks_in_current_sequence_ = false;

  DISALLOW_COPY_AND_ASSIGN(MockRunsTasksInCurrentSequenceTaskRunner);
};

class PostTaskAndReplyImplTest : public testing::Test {
 protected:
  PostTaskAndReplyImplTest() = default;

  void PostTaskAndReplyToMockObject() {
    // Expect the post to succeed.
    EXPECT_TRUE(
        PostTaskAndReplyTaskRunner(post_runner_.get())
            .PostTaskAndReply(
                FROM_HERE,
                BindOnce(&MockObject::Task, Unretained(&mock_object_),
                         MakeRefCounted<ObjectToDelete>(&delete_task_flag_)),
                BindOnce(&MockObject::Reply, Unretained(&mock_object_),
                         MakeRefCounted<ObjectToDelete>(&delete_reply_flag_))));

    // Expect the first task to be posted to |post_runner_|.
    EXPECT_TRUE(post_runner_->HasPendingTask());
    EXPECT_FALSE(reply_runner_->HasPendingTask());
    EXPECT_FALSE(delete_task_flag_);
    EXPECT_FALSE(delete_reply_flag_);
  }

  scoped_refptr<MockRunsTasksInCurrentSequenceTaskRunner> post_runner_ =
      MakeRefCounted<MockRunsTasksInCurrentSequenceTaskRunner>();
  scoped_refptr<MockRunsTasksInCurrentSequenceTaskRunner> reply_runner_ =
      MakeRefCounted<MockRunsTasksInCurrentSequenceTaskRunner>(
          TestMockTimeTaskRunner::Type::kBoundToThread);
  testing::StrictMock<MockObject> mock_object_;
  bool delete_task_flag_ = false;
  bool delete_reply_flag_ = false;

 private:
  DISALLOW_COPY_AND_ASSIGN(PostTaskAndReplyImplTest);
};

}  // namespace

TEST_F(PostTaskAndReplyImplTest, PostTaskAndReply) {
  PostTaskAndReplyToMockObject();

  EXPECT_CALL(mock_object_, Task(_));
  post_runner_->RunUntilIdleWithRunsTasksInCurrentSequence();
  testing::Mock::VerifyAndClear(&mock_object_);
  // The task should have been deleted right after being run.
  EXPECT_TRUE(delete_task_flag_);
  EXPECT_FALSE(delete_reply_flag_);

  // Expect the reply to be posted to |reply_runner_|.
  EXPECT_FALSE(post_runner_->HasPendingTask());
  EXPECT_TRUE(reply_runner_->HasPendingTask());

  EXPECT_CALL(mock_object_, Reply(_));
  reply_runner_->RunUntilIdleWithRunsTasksInCurrentSequence();
  testing::Mock::VerifyAndClear(&mock_object_);
  EXPECT_TRUE(delete_task_flag_);
  // The reply should have been deleted right after being run.
  EXPECT_TRUE(delete_reply_flag_);

  // Expect no pending task in |post_runner_| and |reply_runner_|.
  EXPECT_FALSE(post_runner_->HasPendingTask());
  EXPECT_FALSE(reply_runner_->HasPendingTask());
}

TEST_F(PostTaskAndReplyImplTest, TaskDoesNotRun) {
  PostTaskAndReplyToMockObject();

  // Clear the |post_runner_|. Both callbacks should be scheduled for deletion
  // on the |reply_runner_|.
  post_runner_->ClearPendingTasksWithRunsTasksInCurrentSequence();
  EXPECT_FALSE(post_runner_->HasPendingTask());
  EXPECT_TRUE(reply_runner_->HasPendingTask());
  EXPECT_FALSE(delete_task_flag_);
  EXPECT_FALSE(delete_reply_flag_);

  // Run the |reply_runner_|. Both callbacks should be deleted.
  reply_runner_->RunUntilIdleWithRunsTasksInCurrentSequence();
  EXPECT_TRUE(delete_task_flag_);
  EXPECT_TRUE(delete_reply_flag_);
}

TEST_F(PostTaskAndReplyImplTest, ReplyDoesNotRun) {
  PostTaskAndReplyToMockObject();

  EXPECT_CALL(mock_object_, Task(_));
  post_runner_->RunUntilIdleWithRunsTasksInCurrentSequence();
  testing::Mock::VerifyAndClear(&mock_object_);
  // The task should have been deleted right after being run.
  EXPECT_TRUE(delete_task_flag_);
  EXPECT_FALSE(delete_reply_flag_);

  // Expect the reply to be posted to |reply_runner_|.
  EXPECT_FALSE(post_runner_->HasPendingTask());
  EXPECT_TRUE(reply_runner_->HasPendingTask());

  // Clear the |reply_runner_| queue without running tasks. The reply callback
  // should be deleted.
  reply_runner_->ClearPendingTasksWithRunsTasksInCurrentSequence();
  EXPECT_TRUE(delete_task_flag_);
  EXPECT_TRUE(delete_reply_flag_);
}

}  // namespace internal
}  // namespace base
