// 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 <utility>

#include "base/bind.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/sequence_token.h"
#include "base/task/post_task.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/tests/bindings_test_base.h"
#include "mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace mojo {
namespace test {
namespace {

class TestSyncCommonImpl {
 public:
  TestSyncCommonImpl() {}

  using PingHandler = base::RepeatingCallback<void(base::OnceClosure)>;
  template <typename Func>
  void set_ping_handler(Func handler) {
    ping_handler_ = base::BindLambdaForTesting(handler);
  }

  using EchoHandler =
      base::RepeatingCallback<void(int32_t, base::OnceCallback<void(int32_t)>)>;
  template <typename Func>
  void set_echo_handler(Func handler) {
    echo_handler_ = base::BindLambdaForTesting(handler);
  }

  using AsyncEchoHandler =
      base::RepeatingCallback<void(int32_t, base::OnceCallback<void(int32_t)>)>;
  template <typename Func>
  void set_async_echo_handler(Func handler) {
    async_echo_handler_ = base::BindLambdaForTesting(handler);
  }

  using SendInterfaceHandler =
      base::RepeatingCallback<void(TestSyncAssociatedPtrInfo)>;
  template <typename Func>
  void set_send_interface_handler(Func handler) {
    send_interface_handler_ = base::BindLambdaForTesting(handler);
  }

  using SendRequestHandler =
      base::RepeatingCallback<void(TestSyncAssociatedRequest)>;
  template <typename Func>
  void set_send_request_handler(Func handler) {
    send_request_handler_ = base::BindLambdaForTesting(handler);
  }

  void PingImpl(base::OnceCallback<void()> callback) {
    if (ping_handler_.is_null()) {
      std::move(callback).Run();
      return;
    }
    ping_handler_.Run(std::move(callback));
  }
  void EchoImpl(int32_t value, base::OnceCallback<void(int32_t)> callback) {
    if (echo_handler_.is_null()) {
      std::move(callback).Run(value);
      return;
    }
    echo_handler_.Run(value, std::move(callback));
  }
  void AsyncEchoImpl(int32_t value,
                     base::OnceCallback<void(int32_t)> callback) {
    if (async_echo_handler_.is_null()) {
      std::move(callback).Run(value);
      return;
    }
    async_echo_handler_.Run(value, std::move(callback));
  }
  void SendInterfaceImpl(TestSyncAssociatedPtrInfo ptr) {
    send_interface_handler_.Run(std::move(ptr));
  }
  void SendRequestImpl(TestSyncAssociatedRequest request) {
    send_request_handler_.Run(std::move(request));
  }

 private:
  PingHandler ping_handler_;
  EchoHandler echo_handler_;
  AsyncEchoHandler async_echo_handler_;
  SendInterfaceHandler send_interface_handler_;
  SendRequestHandler send_request_handler_;

  DISALLOW_COPY_AND_ASSIGN(TestSyncCommonImpl);
};

class TestSyncImpl : public TestSync, public TestSyncCommonImpl {
 public:
  explicit TestSyncImpl(TestSyncRequest request)
      : binding_(this, std::move(request)) {}

  // TestSync implementation:
  void Ping(PingCallback callback) override { PingImpl(std::move(callback)); }
  void Echo(int32_t value, EchoCallback callback) override {
    EchoImpl(value, std::move(callback));
  }
  void AsyncEcho(int32_t value, AsyncEchoCallback callback) override {
    AsyncEchoImpl(value, std::move(callback));
  }

  Binding<TestSync>* binding() { return &binding_; }

 private:
  Binding<TestSync> binding_;

  DISALLOW_COPY_AND_ASSIGN(TestSyncImpl);
};

class TestSyncMasterImpl : public TestSyncMaster, public TestSyncCommonImpl {
 public:
  explicit TestSyncMasterImpl(TestSyncMasterRequest request)
      : binding_(this, std::move(request)) {}

  // TestSyncMaster implementation:
  void Ping(PingCallback callback) override { PingImpl(std::move(callback)); }
  void Echo(int32_t value, EchoCallback callback) override {
    EchoImpl(value, std::move(callback));
  }
  void AsyncEcho(int32_t value, AsyncEchoCallback callback) override {
    AsyncEchoImpl(value, std::move(callback));
  }
  void SendInterface(TestSyncAssociatedPtrInfo ptr) override {
    SendInterfaceImpl(std::move(ptr));
  }
  void SendRequest(TestSyncAssociatedRequest request) override {
    SendRequestImpl(std::move(request));
  }

  Binding<TestSyncMaster>* binding() { return &binding_; }

 private:
  Binding<TestSyncMaster> binding_;

  DISALLOW_COPY_AND_ASSIGN(TestSyncMasterImpl);
};

class TestSyncAssociatedImpl : public TestSync, public TestSyncCommonImpl {
 public:
  explicit TestSyncAssociatedImpl(TestSyncAssociatedRequest request)
      : binding_(this, std::move(request)) {}

  // TestSync implementation:
  void Ping(PingCallback callback) override { PingImpl(std::move(callback)); }
  void Echo(int32_t value, EchoCallback callback) override {
    EchoImpl(value, std::move(callback));
  }
  void AsyncEcho(int32_t value, AsyncEchoCallback callback) override {
    AsyncEchoImpl(value, std::move(callback));
  }

  AssociatedBinding<TestSync>* binding() { return &binding_; }

 private:
  AssociatedBinding<TestSync> binding_;

  DISALLOW_COPY_AND_ASSIGN(TestSyncAssociatedImpl);
};

template <typename Interface>
struct ImplTraits;

template <>
struct ImplTraits<TestSync> {
  using Type = TestSyncImpl;
};

template <>
struct ImplTraits<TestSyncMaster> {
  using Type = TestSyncMasterImpl;
};

template <typename Interface>
using ImplTypeFor = typename ImplTraits<Interface>::Type;

// A wrapper for either an InterfacePtr or scoped_refptr<ThreadSafeInterfacePtr>
// that exposes the InterfacePtr interface.
template <typename Interface>
class PtrWrapper {
 public:
  explicit PtrWrapper(InterfacePtr<Interface> ptr) : ptr_(std::move(ptr)) {}

  explicit PtrWrapper(
      scoped_refptr<ThreadSafeInterfacePtr<Interface>> thread_safe_ptr)
      : thread_safe_ptr_(thread_safe_ptr) {}

  PtrWrapper(PtrWrapper&& other) = default;

  Interface* operator->() {
    return thread_safe_ptr_ ? thread_safe_ptr_->get() : ptr_.get();
  }

  void set_connection_error_handler(const base::Closure& error_handler) {
    DCHECK(!thread_safe_ptr_);
    ptr_.set_connection_error_handler(error_handler);
  }

  void reset() {
    ptr_ = nullptr;
    thread_safe_ptr_ = nullptr;
  }

 private:
  InterfacePtr<Interface> ptr_;
  scoped_refptr<ThreadSafeInterfacePtr<Interface>> thread_safe_ptr_;

  DISALLOW_COPY_AND_ASSIGN(PtrWrapper);
};

// The type parameter for SyncMethodCommonTests and
// SyncMethodOnSequenceCommonTests for varying the Interface and whether to use
// InterfacePtr or ThreadSafeInterfacePtr.
template <typename InterfaceT,
          bool use_thread_safe_ptr,
          BindingsTestSerializationMode serialization_mode>
struct TestParams {
  using Interface = InterfaceT;
  static const bool kIsThreadSafeInterfacePtrTest = use_thread_safe_ptr;

  static PtrWrapper<InterfaceT> Wrap(InterfacePtr<Interface> ptr) {
    if (kIsThreadSafeInterfacePtrTest) {
      return PtrWrapper<Interface>(
          ThreadSafeInterfacePtr<Interface>::Create(std::move(ptr)));
    } else {
      return PtrWrapper<Interface>(std::move(ptr));
    }
  }

  static const BindingsTestSerializationMode kSerializationMode =
      serialization_mode;
};

template <typename Interface>
class TestSyncServiceSequence {
 public:
  TestSyncServiceSequence()
      : task_runner_(base::CreateSequencedTaskRunnerWithTraits({})),
        ping_called_(false) {}

  void SetUp(InterfaceRequest<Interface> request) {
    CHECK(task_runner()->RunsTasksInCurrentSequence());
    impl_.reset(new ImplTypeFor<Interface>(std::move(request)));
    impl_->set_ping_handler([this](typename Interface::PingCallback callback) {
      {
        base::AutoLock locker(lock_);
        ping_called_ = true;
      }
      std::move(callback).Run();
    });
  }

  void TearDown() {
    CHECK(task_runner()->RunsTasksInCurrentSequence());
    impl_.reset();
  }

  base::SequencedTaskRunner* task_runner() { return task_runner_.get(); }
  bool ping_called() const {
    base::AutoLock locker(lock_);
    return ping_called_;
  }

 private:
  scoped_refptr<base::SequencedTaskRunner> task_runner_;

  std::unique_ptr<ImplTypeFor<Interface>> impl_;

  mutable base::Lock lock_;
  bool ping_called_;

  DISALLOW_COPY_AND_ASSIGN(TestSyncServiceSequence);
};

class SyncMethodTest : public testing::Test {
 public:
  SyncMethodTest() {}
  ~SyncMethodTest() override { base::RunLoop().RunUntilIdle(); }

 protected:
  base::test::ScopedTaskEnvironment task_environment;
};

template <typename TypeParam>
class SyncMethodCommonTest : public SyncMethodTest {
 public:
  SyncMethodCommonTest() {}
  ~SyncMethodCommonTest() override {}

  void SetUp() override {
    BindingsTestBase::SetupSerializationBehavior(TypeParam::kSerializationMode);
  }
};

class SyncMethodAssociatedTest : public SyncMethodTest {
 public:
  SyncMethodAssociatedTest() {}
  ~SyncMethodAssociatedTest() override {}

 protected:
  void SetUp() override {
    master_impl_.reset(new TestSyncMasterImpl(MakeRequest(&master_ptr_)));

    asso_request_ = MakeRequest(&asso_ptr_info_);
    opposite_asso_request_ = MakeRequest(&opposite_asso_ptr_info_);

    master_impl_->set_send_interface_handler(
        [this](TestSyncAssociatedPtrInfo ptr) {
          opposite_asso_ptr_info_ = std::move(ptr);
        });
    base::RunLoop run_loop;
    master_impl_->set_send_request_handler(
        [this, &run_loop](TestSyncAssociatedRequest request) {
          asso_request_ = std::move(request);
          run_loop.Quit();
        });

    master_ptr_->SendInterface(std::move(opposite_asso_ptr_info_));
    master_ptr_->SendRequest(std::move(asso_request_));
    run_loop.Run();
  }

  void TearDown() override {
    asso_ptr_info_ = TestSyncAssociatedPtrInfo();
    asso_request_ = TestSyncAssociatedRequest();
    opposite_asso_ptr_info_ = TestSyncAssociatedPtrInfo();
    opposite_asso_request_ = TestSyncAssociatedRequest();

    master_ptr_ = nullptr;
    master_impl_.reset();
  }

  InterfacePtr<TestSyncMaster> master_ptr_;
  std::unique_ptr<TestSyncMasterImpl> master_impl_;

  // An associated interface whose binding lives at the |master_impl_| side.
  TestSyncAssociatedPtrInfo asso_ptr_info_;
  TestSyncAssociatedRequest asso_request_;

  // An associated interface whose binding lives at the |master_ptr_| side.
  TestSyncAssociatedPtrInfo opposite_asso_ptr_info_;
  TestSyncAssociatedRequest opposite_asso_request_;
};

void SetFlagAndRunClosure(bool* flag, const base::Closure& closure) {
  *flag = true;
  closure.Run();
}

void ExpectValueAndRunClosure(int32_t expected_value,
                              const base::Closure& closure,
                              int32_t value) {
  EXPECT_EQ(expected_value, value);
  closure.Run();
}

template <typename Func>
void CallAsyncEchoCallback(Func func, int32_t value) {
  func(value);
}

template <typename Func>
TestSync::AsyncEchoCallback BindAsyncEchoCallback(Func func) {
  return base::Bind(&CallAsyncEchoCallback<Func>, func);
}

class SequencedTaskRunnerTestBase;

void RunTestOnSequencedTaskRunner(
    std::unique_ptr<SequencedTaskRunnerTestBase> test);

class SequencedTaskRunnerTestBase {
 public:
  virtual ~SequencedTaskRunnerTestBase() = default;

  void RunTest() {
    SetUp();
    Run();
  }

  virtual void Run() = 0;

  virtual void SetUp() {}
  virtual void TearDown() {}

 protected:
  void Done() {
    TearDown();
    task_runner_->PostTask(FROM_HERE, quit_closure_);
    delete this;
  }

  base::Closure DoneClosure() {
    return base::Bind(&SequencedTaskRunnerTestBase::Done,
                      base::Unretained(this));
  }

 private:
  friend void RunTestOnSequencedTaskRunner(
      std::unique_ptr<SequencedTaskRunnerTestBase> test);

  void Init(const base::Closure& quit_closure) {
    task_runner_ = base::SequencedTaskRunnerHandle::Get();
    quit_closure_ = quit_closure;
  }

  scoped_refptr<base::SequencedTaskRunner> task_runner_;
  base::Closure quit_closure_;
};

// A helper class to launch tests on a SequencedTaskRunner. This is necessary
// so gtest can instantiate copies for each |TypeParam|.
template <typename TypeParam>
class SequencedTaskRunnerTestLauncher : public testing::Test {
  base::test::ScopedTaskEnvironment task_environment;
};

// Similar to SyncMethodCommonTest, but the test body runs on a
// SequencedTaskRunner.
template <typename TypeParam>
class SyncMethodOnSequenceCommonTest : public SequencedTaskRunnerTestBase {
 public:
  void SetUp() override {
    BindingsTestBase::SetupSerializationBehavior(TypeParam::kSerializationMode);
    impl_ = std::make_unique<ImplTypeFor<typename TypeParam::Interface>>(
        MakeRequest(&ptr_));
  }

 protected:
  InterfacePtr<typename TypeParam::Interface> ptr_;
  std::unique_ptr<ImplTypeFor<typename TypeParam::Interface>> impl_;
};

void RunTestOnSequencedTaskRunner(
    std::unique_ptr<SequencedTaskRunnerTestBase> test) {
  base::RunLoop run_loop;
  test->Init(run_loop.QuitClosure());
  base::CreateSequencedTaskRunnerWithTraits({base::WithBaseSyncPrimitives()})
      ->PostTask(FROM_HERE, base::Bind(&SequencedTaskRunnerTestBase::RunTest,
                                       base::Unretained(test.release())));
  run_loop.Run();
}

// TestSync (without associated interfaces) and TestSyncMaster (with associated
// interfaces) exercise MultiplexRouter with different configurations.
// Each test is run once with an InterfacePtr and once with a
// ThreadSafeInterfacePtr to ensure that they behave the same with respect to
// sync calls. Finally, all such combinations are tested in different message
// serialization modes.
using InterfaceTypes = testing::Types<
    TestParams<TestSync,
               true,
               BindingsTestSerializationMode::kSerializeBeforeSend>,
    TestParams<TestSync,
               false,
               BindingsTestSerializationMode::kSerializeBeforeSend>,
    TestParams<TestSyncMaster,
               true,
               BindingsTestSerializationMode::kSerializeBeforeSend>,
    TestParams<TestSyncMaster,
               false,
               BindingsTestSerializationMode::kSerializeBeforeSend>,
    TestParams<TestSync,
               true,
               BindingsTestSerializationMode::kSerializeBeforeDispatch>,
    TestParams<TestSync,
               false,
               BindingsTestSerializationMode::kSerializeBeforeDispatch>,
    TestParams<TestSyncMaster,
               true,
               BindingsTestSerializationMode::kSerializeBeforeDispatch>,
    TestParams<TestSyncMaster,
               false,
               BindingsTestSerializationMode::kSerializeBeforeDispatch>,
    TestParams<TestSync, true, BindingsTestSerializationMode::kNeverSerialize>,
    TestParams<TestSync, false, BindingsTestSerializationMode::kNeverSerialize>,
    TestParams<TestSyncMaster,
               true,
               BindingsTestSerializationMode::kNeverSerialize>,
    TestParams<TestSyncMaster,
               false,
               BindingsTestSerializationMode::kNeverSerialize>>;

TYPED_TEST_CASE(SyncMethodCommonTest, InterfaceTypes);
TYPED_TEST_CASE(SequencedTaskRunnerTestLauncher, InterfaceTypes);

TYPED_TEST(SyncMethodCommonTest, CallSyncMethodAsynchronously) {
  using Interface = typename TypeParam::Interface;
  InterfacePtr<Interface> interface_ptr;
  ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr));
  auto ptr = TypeParam::Wrap(std::move(interface_ptr));

  base::RunLoop run_loop;
  ptr->Echo(123, base::Bind(&ExpectValueAndRunClosure, 123,
                            run_loop.QuitClosure()));
  run_loop.Run();
}

#define SEQUENCED_TASK_RUNNER_TYPED_TEST_NAME(fixture_name, name) \
  fixture_name##name##_SequencedTaskRunnerTestSuffix

#define SEQUENCED_TASK_RUNNER_TYPED_TEST(fixture_name, name)        \
  template <typename TypeParam>                                     \
  class SEQUENCED_TASK_RUNNER_TYPED_TEST_NAME(fixture_name, name)   \
      : public fixture_name<TypeParam> {                            \
    void Run() override;                                            \
  };                                                                \
  TYPED_TEST(SequencedTaskRunnerTestLauncher, name) {               \
    RunTestOnSequencedTaskRunner(                                   \
        std::make_unique<SEQUENCED_TASK_RUNNER_TYPED_TEST_NAME(     \
                             fixture_name, name) < TypeParam>> ()); \
  }                                                                 \
  template <typename TypeParam>                                     \
  void SEQUENCED_TASK_RUNNER_TYPED_TEST_NAME(fixture_name,          \
                                             name)<TypeParam>::Run()

#define SEQUENCED_TASK_RUNNER_TYPED_TEST_F(fixture_name, name)      \
  template <typename TypeParam>                                     \
  class SEQUENCED_TASK_RUNNER_TYPED_TEST_NAME(fixture_name, name);  \
  TYPED_TEST(SequencedTaskRunnerTestLauncher, name) {               \
    RunTestOnSequencedTaskRunner(                                   \
        std::make_unique<SEQUENCED_TASK_RUNNER_TYPED_TEST_NAME(     \
                             fixture_name, name) < TypeParam>> ()); \
  }                                                                 \
  template <typename TypeParam>                                     \
  class SEQUENCED_TASK_RUNNER_TYPED_TEST_NAME(fixture_name, name)   \
      : public fixture_name<TypeParam>

SEQUENCED_TASK_RUNNER_TYPED_TEST(SyncMethodOnSequenceCommonTest,
                                 CallSyncMethodAsynchronously) {
  this->ptr_->Echo(
      123, base::Bind(&ExpectValueAndRunClosure, 123, this->DoneClosure()));
}

TYPED_TEST(SyncMethodCommonTest, BasicSyncCalls) {
  using Interface = typename TypeParam::Interface;
  InterfacePtr<Interface> interface_ptr;
  InterfaceRequest<Interface> request = MakeRequest(&interface_ptr);
  auto ptr = TypeParam::Wrap(std::move(interface_ptr));

  TestSyncServiceSequence<Interface> service_sequence;
  service_sequence.task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&TestSyncServiceSequence<Interface>::SetUp,
                 base::Unretained(&service_sequence), base::Passed(&request)));
  ASSERT_TRUE(ptr->Ping());
  ASSERT_TRUE(service_sequence.ping_called());

  int32_t output_value = -1;
  ASSERT_TRUE(ptr->Echo(42, &output_value));
  ASSERT_EQ(42, output_value);

  base::RunLoop run_loop;
  service_sequence.task_runner()->PostTaskAndReply(
      FROM_HERE,
      base::Bind(&TestSyncServiceSequence<Interface>::TearDown,
                 base::Unretained(&service_sequence)),
      run_loop.QuitClosure());
  run_loop.Run();
}

TYPED_TEST(SyncMethodCommonTest, ReenteredBySyncMethodBinding) {
  // Test that an interface pointer waiting for a sync call response can be
  // reentered by a binding serving sync methods on the same thread.

  using Interface = typename TypeParam::Interface;
  InterfacePtr<Interface> interface_ptr;
  // The binding lives on the same thread as the interface pointer.
  ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr));
  auto ptr = TypeParam::Wrap(std::move(interface_ptr));
  int32_t output_value = -1;
  ASSERT_TRUE(ptr->Echo(42, &output_value));
  EXPECT_EQ(42, output_value);
}

SEQUENCED_TASK_RUNNER_TYPED_TEST(SyncMethodOnSequenceCommonTest,
                                 ReenteredBySyncMethodBinding) {
  // Test that an interface pointer waiting for a sync call response can be
  // reentered by a binding serving sync methods on the same thread.

  int32_t output_value = -1;
  ASSERT_TRUE(this->ptr_->Echo(42, &output_value));
  EXPECT_EQ(42, output_value);
  this->Done();
}

TYPED_TEST(SyncMethodCommonTest, InterfacePtrDestroyedDuringSyncCall) {
  // Test that it won't result in crash or hang if an interface pointer is
  // destroyed while it is waiting for a sync call response.

  using Interface = typename TypeParam::Interface;
  InterfacePtr<Interface> interface_ptr;
  ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr));
  auto ptr = TypeParam::Wrap(std::move(interface_ptr));
  impl.set_ping_handler([&ptr](TestSync::PingCallback callback) {
    ptr.reset();
    std::move(callback).Run();
  });
  ASSERT_FALSE(ptr->Ping());
}

SEQUENCED_TASK_RUNNER_TYPED_TEST(SyncMethodOnSequenceCommonTest,
                                 InterfacePtrDestroyedDuringSyncCall) {
  // Test that it won't result in crash or hang if an interface pointer is
  // destroyed while it is waiting for a sync call response.

  auto* ptr = &this->ptr_;
  this->impl_->set_ping_handler([ptr](TestSync::PingCallback callback) {
    ptr->reset();
    std::move(callback).Run();
  });
  ASSERT_FALSE(this->ptr_->Ping());
  this->Done();
}

TYPED_TEST(SyncMethodCommonTest, BindingDestroyedDuringSyncCall) {
  // Test that it won't result in crash or hang if a binding is
  // closed (and therefore the message pipe handle is closed) while the
  // corresponding interface pointer is waiting for a sync call response.

  using Interface = typename TypeParam::Interface;
  InterfacePtr<Interface> interface_ptr;
  ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr));
  auto ptr = TypeParam::Wrap(std::move(interface_ptr));
  impl.set_ping_handler([&impl](TestSync::PingCallback callback) {
    impl.binding()->Close();
    std::move(callback).Run();
  });
  ASSERT_FALSE(ptr->Ping());
}

SEQUENCED_TASK_RUNNER_TYPED_TEST(SyncMethodOnSequenceCommonTest,
                                 BindingDestroyedDuringSyncCall) {
  // Test that it won't result in crash or hang if a binding is
  // closed (and therefore the message pipe handle is closed) while the
  // corresponding interface pointer is waiting for a sync call response.

  auto& impl = *this->impl_;
  this->impl_->set_ping_handler([&impl](TestSync::PingCallback callback) {
    impl.binding()->Close();
    std::move(callback).Run();
  });
  ASSERT_FALSE(this->ptr_->Ping());
  this->Done();
}

TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithInOrderResponses) {
  // Test that we can call a sync method on an interface ptr, while there is
  // already a sync call ongoing. The responses arrive in order.

  using Interface = typename TypeParam::Interface;
  InterfacePtr<Interface> interface_ptr;
  ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr));
  auto ptr = TypeParam::Wrap(std::move(interface_ptr));

  // The same variable is used to store the output of the two sync calls, in
  // order to test that responses are handled in the correct order.
  int32_t result_value = -1;

  bool first_call = true;
  impl.set_echo_handler([&first_call, &ptr, &result_value](
                            int32_t value, TestSync::EchoCallback callback) {
    if (first_call) {
      first_call = false;
      ASSERT_TRUE(ptr->Echo(456, &result_value));
      EXPECT_EQ(456, result_value);
    }
    std::move(callback).Run(value);
  });

  ASSERT_TRUE(ptr->Echo(123, &result_value));
  EXPECT_EQ(123, result_value);
}

SEQUENCED_TASK_RUNNER_TYPED_TEST(SyncMethodOnSequenceCommonTest,
                                 NestedSyncCallsWithInOrderResponses) {
  // Test that we can call a sync method on an interface ptr, while there is
  // already a sync call ongoing. The responses arrive in order.

  // The same variable is used to store the output of the two sync calls, in
  // order to test that responses are handled in the correct order.
  int32_t result_value = -1;

  bool first_call = true;
  auto& ptr = this->ptr_;
  auto& impl = *this->impl_;
  impl.set_echo_handler([&first_call, &ptr, &result_value](
                            int32_t value, TestSync::EchoCallback callback) {
    if (first_call) {
      first_call = false;
      ASSERT_TRUE(ptr->Echo(456, &result_value));
      EXPECT_EQ(456, result_value);
    }
    std::move(callback).Run(value);
  });

  ASSERT_TRUE(ptr->Echo(123, &result_value));
  EXPECT_EQ(123, result_value);
  this->Done();
}

TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithOutOfOrderResponses) {
  // Test that we can call a sync method on an interface ptr, while there is
  // already a sync call ongoing. The responses arrive out of order.

  using Interface = typename TypeParam::Interface;
  InterfacePtr<Interface> interface_ptr;
  ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr));
  auto ptr = TypeParam::Wrap(std::move(interface_ptr));

  // The same variable is used to store the output of the two sync calls, in
  // order to test that responses are handled in the correct order.
  int32_t result_value = -1;

  bool first_call = true;
  impl.set_echo_handler([&first_call, &ptr, &result_value](
                            int32_t value, TestSync::EchoCallback callback) {
    std::move(callback).Run(value);
    if (first_call) {
      first_call = false;
      ASSERT_TRUE(ptr->Echo(456, &result_value));
      EXPECT_EQ(456, result_value);
    }
  });

  ASSERT_TRUE(ptr->Echo(123, &result_value));
  EXPECT_EQ(123, result_value);
}

SEQUENCED_TASK_RUNNER_TYPED_TEST(SyncMethodOnSequenceCommonTest,
                                 NestedSyncCallsWithOutOfOrderResponses) {
  // Test that we can call a sync method on an interface ptr, while there is
  // already a sync call ongoing. The responses arrive out of order.

  // The same variable is used to store the output of the two sync calls, in
  // order to test that responses are handled in the correct order.
  int32_t result_value = -1;

  bool first_call = true;
  auto& ptr = this->ptr_;
  auto& impl = *this->impl_;
  impl.set_echo_handler([&first_call, &ptr, &result_value](
                            int32_t value, TestSync::EchoCallback callback) {
    std::move(callback).Run(value);
    if (first_call) {
      first_call = false;
      ASSERT_TRUE(ptr->Echo(456, &result_value));
      EXPECT_EQ(456, result_value);
    }
  });

  ASSERT_TRUE(ptr->Echo(123, &result_value));
  EXPECT_EQ(123, result_value);
  this->Done();
}

TYPED_TEST(SyncMethodCommonTest, AsyncResponseQueuedDuringSyncCall) {
  // Test that while an interface pointer is waiting for the response to a sync
  // call, async responses are queued until the sync call completes.

  using Interface = typename TypeParam::Interface;
  InterfacePtr<Interface> interface_ptr;
  ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr));
  auto ptr = TypeParam::Wrap(std::move(interface_ptr));

  int32_t async_echo_request_value = -1;
  TestSync::AsyncEchoCallback async_echo_request_callback;
  base::RunLoop run_loop1;
  impl.set_async_echo_handler(
      [&async_echo_request_value, &async_echo_request_callback, &run_loop1](
          int32_t value, TestSync::AsyncEchoCallback callback) {
        async_echo_request_value = value;
        async_echo_request_callback = std::move(callback);
        run_loop1.Quit();
      });

  bool async_echo_response_dispatched = false;
  base::RunLoop run_loop2;
  ptr->AsyncEcho(
      123,
      BindAsyncEchoCallback(
         [&async_echo_response_dispatched, &run_loop2](int32_t result) {
           async_echo_response_dispatched = true;
           EXPECT_EQ(123, result);
           run_loop2.Quit();
         }));
  // Run until the AsyncEcho request reaches the service side.
  run_loop1.Run();

  impl.set_echo_handler(
      [&async_echo_request_value, &async_echo_request_callback](
          int32_t value, TestSync::EchoCallback callback) {
        // Send back the async response first.
        EXPECT_FALSE(async_echo_request_callback.is_null());
        std::move(async_echo_request_callback).Run(async_echo_request_value);

        std::move(callback).Run(value);
      });

  int32_t result_value = -1;
  ASSERT_TRUE(ptr->Echo(456, &result_value));
  EXPECT_EQ(456, result_value);

  // Although the AsyncEcho response arrives before the Echo response, it should
  // be queued and not yet dispatched.
  EXPECT_FALSE(async_echo_response_dispatched);

  // Run until the AsyncEcho response is dispatched.
  run_loop2.Run();

  EXPECT_TRUE(async_echo_response_dispatched);
}

SEQUENCED_TASK_RUNNER_TYPED_TEST_F(SyncMethodOnSequenceCommonTest,
                                   AsyncResponseQueuedDuringSyncCall) {
  // Test that while an interface pointer is waiting for the response to a sync
  // call, async responses are queued until the sync call completes.

  void Run() override {
    this->impl_->set_async_echo_handler(
        [this](int32_t value, TestSync::AsyncEchoCallback callback) {
          async_echo_request_value_ = value;
          async_echo_request_callback_ = std::move(callback);
          OnAsyncEchoReceived();
        });

    this->ptr_->AsyncEcho(123, BindAsyncEchoCallback([this](int32_t result) {
                            async_echo_response_dispatched_ = true;
                            EXPECT_EQ(123, result);
                            EXPECT_TRUE(async_echo_response_dispatched_);
                            this->Done();
                          }));
  }

  // Called when the AsyncEcho request reaches the service side.
  void OnAsyncEchoReceived() {
    this->impl_->set_echo_handler([this](int32_t value,
                                         TestSync::EchoCallback callback) {
      // Send back the async response first.
      EXPECT_FALSE(async_echo_request_callback_.is_null());
      std::move(async_echo_request_callback_).Run(async_echo_request_value_);

      std::move(callback).Run(value);
    });

    int32_t result_value = -1;
    ASSERT_TRUE(this->ptr_->Echo(456, &result_value));
    EXPECT_EQ(456, result_value);

    // Although the AsyncEcho response arrives before the Echo response, it
    // should be queued and not yet dispatched.
    EXPECT_FALSE(async_echo_response_dispatched_);
  }

  int32_t async_echo_request_value_ = -1;
  TestSync::AsyncEchoCallback async_echo_request_callback_;
  bool async_echo_response_dispatched_ = false;
};

TYPED_TEST(SyncMethodCommonTest, AsyncRequestQueuedDuringSyncCall) {
  // Test that while an interface pointer is waiting for the response to a sync
  // call, async requests for a binding running on the same thread are queued
  // until the sync call completes.

  using Interface = typename TypeParam::Interface;
  InterfacePtr<Interface> interface_ptr;
  ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr));
  auto ptr = TypeParam::Wrap(std::move(interface_ptr));

  bool async_echo_request_dispatched = false;
  impl.set_async_echo_handler(
      [&async_echo_request_dispatched](int32_t value,
                                       TestSync::AsyncEchoCallback callback) {
        async_echo_request_dispatched = true;
        std::move(callback).Run(value);
      });

  bool async_echo_response_dispatched = false;
  base::RunLoop run_loop;
  ptr->AsyncEcho(
      123,
      BindAsyncEchoCallback(
         [&async_echo_response_dispatched, &run_loop](int32_t result) {
           async_echo_response_dispatched = true;
           EXPECT_EQ(123, result);
           run_loop.Quit();
         }));

  impl.set_echo_handler([&async_echo_request_dispatched](
                            int32_t value, TestSync::EchoCallback callback) {
    // Although the AsyncEcho request is sent before the Echo request, it
    // shouldn't be dispatched yet at this point, because there is an ongoing
    // sync call on the same thread.
    EXPECT_FALSE(async_echo_request_dispatched);
    std::move(callback).Run(value);
  });

  int32_t result_value = -1;
  ASSERT_TRUE(ptr->Echo(456, &result_value));
  EXPECT_EQ(456, result_value);

  // Although the AsyncEcho request is sent before the Echo request, it
  // shouldn't be dispatched yet.
  EXPECT_FALSE(async_echo_request_dispatched);

  // Run until the AsyncEcho response is dispatched.
  run_loop.Run();

  EXPECT_TRUE(async_echo_response_dispatched);
}

SEQUENCED_TASK_RUNNER_TYPED_TEST_F(SyncMethodOnSequenceCommonTest,
                                   AsyncRequestQueuedDuringSyncCall) {
  // Test that while an interface pointer is waiting for the response to a sync
  // call, async requests for a binding running on the same thread are queued
  // until the sync call completes.
  void Run() override {
    this->impl_->set_async_echo_handler(
        [this](int32_t value, TestSync::AsyncEchoCallback callback) {
          async_echo_request_dispatched_ = true;
          std::move(callback).Run(value);
        });

    this->ptr_->AsyncEcho(123, BindAsyncEchoCallback([this](int32_t result) {
                            EXPECT_EQ(123, result);
                            this->Done();
                          }));

    this->impl_->set_echo_handler(
        [this](int32_t value, TestSync::EchoCallback callback) {
          // Although the AsyncEcho request is sent before the Echo request, it
          // shouldn't be dispatched yet at this point, because there is an
          // ongoing
          // sync call on the same thread.
          EXPECT_FALSE(async_echo_request_dispatched_);
          std::move(callback).Run(value);
        });

    int32_t result_value = -1;
    ASSERT_TRUE(this->ptr_->Echo(456, &result_value));
    EXPECT_EQ(456, result_value);

    // Although the AsyncEcho request is sent before the Echo request, it
    // shouldn't be dispatched yet.
    EXPECT_FALSE(async_echo_request_dispatched_);
  }
  bool async_echo_request_dispatched_ = false;
};

TYPED_TEST(SyncMethodCommonTest,
           QueuedMessagesProcessedBeforeErrorNotification) {
  // Test that while an interface pointer is waiting for the response to a sync
  // call, async responses are queued. If the message pipe is disconnected
  // before the queued messages are processed, the connection error
  // notification is delayed until all the queued messages are processed.

  // ThreadSafeInterfacePtr doesn't guarantee that messages are delivered before
  // error notifications, so skip it for this test.
  if (TypeParam::kIsThreadSafeInterfacePtrTest)
    return;

  using Interface = typename TypeParam::Interface;
  InterfacePtr<Interface> ptr;
  ImplTypeFor<Interface> impl(MakeRequest(&ptr));

  int32_t async_echo_request_value = -1;
  TestSync::AsyncEchoCallback async_echo_request_callback;
  base::RunLoop run_loop1;
  impl.set_async_echo_handler(
      [&async_echo_request_value, &async_echo_request_callback, &run_loop1](
          int32_t value, TestSync::AsyncEchoCallback callback) {
        async_echo_request_value = value;
        async_echo_request_callback = std::move(callback);
        run_loop1.Quit();
      });

  bool async_echo_response_dispatched = false;
  bool connection_error_dispatched = false;
  base::RunLoop run_loop2;
  ptr->AsyncEcho(123, BindAsyncEchoCallback([&async_echo_response_dispatched,
                                             &connection_error_dispatched, &ptr,
                                             &run_loop2](int32_t result) {
                   async_echo_response_dispatched = true;
                   // At this point, error notification should not be dispatched
                   // yet.
                   EXPECT_FALSE(connection_error_dispatched);
                   EXPECT_FALSE(ptr.encountered_error());
                   EXPECT_EQ(123, result);
                   run_loop2.Quit();
                 }));
  // Run until the AsyncEcho request reaches the service side.
  run_loop1.Run();

  impl.set_echo_handler(
      [&impl, &async_echo_request_value, &async_echo_request_callback](
          int32_t value, TestSync::EchoCallback callback) {
        // Send back the async response first.
        EXPECT_FALSE(async_echo_request_callback.is_null());
        std::move(async_echo_request_callback).Run(async_echo_request_value);

        impl.binding()->Close();
      });

  base::RunLoop run_loop3;
  ptr.set_connection_error_handler(base::Bind(&SetFlagAndRunClosure,
                                              &connection_error_dispatched,
                                              run_loop3.QuitClosure()));

  int32_t result_value = -1;
  ASSERT_FALSE(ptr->Echo(456, &result_value));
  EXPECT_EQ(-1, result_value);
  ASSERT_FALSE(connection_error_dispatched);
  EXPECT_FALSE(ptr.encountered_error());

  // Although the AsyncEcho response arrives before the Echo response, it should
  // be queued and not yet dispatched.
  EXPECT_FALSE(async_echo_response_dispatched);

  // Run until the AsyncEcho response is dispatched.
  run_loop2.Run();

  EXPECT_TRUE(async_echo_response_dispatched);

  // Run until the error notification is dispatched.
  run_loop3.Run();

  ASSERT_TRUE(connection_error_dispatched);
  EXPECT_TRUE(ptr.encountered_error());
}

SEQUENCED_TASK_RUNNER_TYPED_TEST_F(
    SyncMethodOnSequenceCommonTest,
    QueuedMessagesProcessedBeforeErrorNotification) {
  // Test that while an interface pointer is waiting for the response to a sync
  // call, async responses are queued. If the message pipe is disconnected
  // before the queued messages are processed, the connection error
  // notification is delayed until all the queued messages are processed.

  void Run() override {
    this->impl_->set_async_echo_handler(
        [this](int32_t value, TestSync::AsyncEchoCallback callback) {
          OnAsyncEchoReachedService(value, std::move(callback));
        });

    this->ptr_->AsyncEcho(123, BindAsyncEchoCallback([this](int32_t result) {
                            async_echo_response_dispatched_ = true;
                            // At this point, error notification should not be
                            // dispatched
                            // yet.
                            EXPECT_FALSE(connection_error_dispatched_);
                            EXPECT_FALSE(this->ptr_.encountered_error());
                            EXPECT_EQ(123, result);
                            EXPECT_TRUE(async_echo_response_dispatched_);
                          }));
  }

  void OnAsyncEchoReachedService(int32_t value,
                                 TestSync::AsyncEchoCallback callback) {
    async_echo_request_value_ = value;
    async_echo_request_callback_ = std::move(callback);
    this->impl_->set_echo_handler([this](int32_t value,
                                         TestSync::EchoCallback callback) {
      // Send back the async response first.
      EXPECT_FALSE(async_echo_request_callback_.is_null());
      std::move(async_echo_request_callback_).Run(async_echo_request_value_);

      this->impl_->binding()->Close();
    });

    this->ptr_.set_connection_error_handler(
        base::BindOnce(&SetFlagAndRunClosure, &connection_error_dispatched_,
                       base::BindLambdaForTesting(
                           [this]() { OnErrorNotificationDispatched(); })));

    int32_t result_value = -1;
    ASSERT_FALSE(this->ptr_->Echo(456, &result_value));
    EXPECT_EQ(-1, result_value);
    ASSERT_FALSE(connection_error_dispatched_);
    EXPECT_FALSE(this->ptr_.encountered_error());

    // Although the AsyncEcho response arrives before the Echo response, it
    // should
    // be queued and not yet dispatched.
    EXPECT_FALSE(async_echo_response_dispatched_);
  }

  void OnErrorNotificationDispatched() {
    ASSERT_TRUE(connection_error_dispatched_);
    EXPECT_TRUE(this->ptr_.encountered_error());
    this->Done();
  }

  int32_t async_echo_request_value_ = -1;
  TestSync::AsyncEchoCallback async_echo_request_callback_;
  bool async_echo_response_dispatched_ = false;
  bool connection_error_dispatched_ = false;
};

TYPED_TEST(SyncMethodCommonTest, InvalidMessageDuringSyncCall) {
  // Test that while an interface pointer is waiting for the response to a sync
  // call, an invalid incoming message will disconnect the message pipe, cause
  // the sync call to return false, and run the connection error handler
  // asynchronously.

  using Interface = typename TypeParam::Interface;
  MessagePipe pipe;

  InterfacePtr<Interface> interface_ptr;
  interface_ptr.Bind(InterfacePtrInfo<Interface>(std::move(pipe.handle0), 0u));
  auto ptr = TypeParam::Wrap(std::move(interface_ptr));

  MessagePipeHandle raw_binding_handle = pipe.handle1.get();
  ImplTypeFor<Interface> impl(
      InterfaceRequest<Interface>(std::move(pipe.handle1)));

  impl.set_echo_handler([&raw_binding_handle](int32_t value,
                                              TestSync::EchoCallback callback) {
    // Write a 1-byte message, which is considered invalid.
    char invalid_message = 0;
    MojoResult result =
        WriteMessageRaw(raw_binding_handle, &invalid_message, 1u, nullptr, 0u,
                        MOJO_WRITE_MESSAGE_FLAG_NONE);
    ASSERT_EQ(MOJO_RESULT_OK, result);
    std::move(callback).Run(value);
  });

  bool connection_error_dispatched = false;
  base::RunLoop run_loop;
  // ThreadSafeInterfacePtr doesn't support setting connection error handlers.
  if (!TypeParam::kIsThreadSafeInterfacePtrTest) {
    ptr.set_connection_error_handler(base::Bind(&SetFlagAndRunClosure,
                                                &connection_error_dispatched,
                                                run_loop.QuitClosure()));
  }

  int32_t result_value = -1;
  ASSERT_FALSE(ptr->Echo(456, &result_value));
  EXPECT_EQ(-1, result_value);
  ASSERT_FALSE(connection_error_dispatched);

  if (!TypeParam::kIsThreadSafeInterfacePtrTest) {
    run_loop.Run();
    ASSERT_TRUE(connection_error_dispatched);
  }
}

SEQUENCED_TASK_RUNNER_TYPED_TEST_F(SyncMethodOnSequenceCommonTest,
                                   InvalidMessageDuringSyncCall) {
  // Test that while an interface pointer is waiting for the response to a sync
  // call, an invalid incoming message will disconnect the message pipe, cause
  // the sync call to return false, and run the connection error handler
  // asynchronously.

  void Run() override {
    MessagePipe pipe;

    using InterfaceType = typename TypeParam::Interface;
    this->ptr_.Bind(
        InterfacePtrInfo<InterfaceType>(std::move(pipe.handle0), 0u));

    MessagePipeHandle raw_binding_handle = pipe.handle1.get();
    this->impl_ = std::make_unique<ImplTypeFor<InterfaceType>>(
        InterfaceRequest<InterfaceType>(std::move(pipe.handle1)));

    this->impl_->set_echo_handler(
        [raw_binding_handle](int32_t value, TestSync::EchoCallback callback) {
          // Write a 1-byte message, which is considered invalid.
          char invalid_message = 0;
          MojoResult result =
              WriteMessageRaw(raw_binding_handle, &invalid_message, 1u, nullptr,
                              0u, MOJO_WRITE_MESSAGE_FLAG_NONE);
          ASSERT_EQ(MOJO_RESULT_OK, result);
          std::move(callback).Run(value);
        });

    this->ptr_.set_connection_error_handler(
        base::BindLambdaForTesting([this]() {
          connection_error_dispatched_ = true;
          this->Done();
        }));

    int32_t result_value = -1;
    ASSERT_FALSE(this->ptr_->Echo(456, &result_value));
    EXPECT_EQ(-1, result_value);
    ASSERT_FALSE(connection_error_dispatched_);
  }
  bool connection_error_dispatched_ = false;
};

TEST_F(SyncMethodAssociatedTest, ReenteredBySyncMethodAssoBindingOfSameRouter) {
  // Test that an interface pointer waiting for a sync call response can be
  // reentered by an associated binding serving sync methods on the same thread.
  // The associated binding belongs to the same MultiplexRouter as the waiting
  // interface pointer.

  TestSyncAssociatedImpl opposite_asso_impl(std::move(opposite_asso_request_));
  TestSyncAssociatedPtr opposite_asso_ptr;
  opposite_asso_ptr.Bind(std::move(opposite_asso_ptr_info_));

  master_impl_->set_echo_handler(
      [&opposite_asso_ptr](int32_t value,
                           TestSyncMaster::EchoCallback callback) {
        int32_t result_value = -1;

        ASSERT_TRUE(opposite_asso_ptr->Echo(123, &result_value));
        EXPECT_EQ(123, result_value);
        std::move(callback).Run(value);
      });

  int32_t result_value = -1;
  ASSERT_TRUE(master_ptr_->Echo(456, &result_value));
  EXPECT_EQ(456, result_value);
}

TEST_F(SyncMethodAssociatedTest,
       ReenteredBySyncMethodAssoBindingOfDifferentRouter) {
  // Test that an interface pointer waiting for a sync call response can be
  // reentered by an associated binding serving sync methods on the same thread.
  // The associated binding belongs to a different MultiplexRouter as the
  // waiting interface pointer.

  TestSyncAssociatedImpl asso_impl(std::move(asso_request_));
  TestSyncAssociatedPtr asso_ptr;
  asso_ptr.Bind(std::move(asso_ptr_info_));

  master_impl_->set_echo_handler(
      [&asso_ptr](int32_t value, TestSyncMaster::EchoCallback callback) {
        int32_t result_value = -1;

        ASSERT_TRUE(asso_ptr->Echo(123, &result_value));
        EXPECT_EQ(123, result_value);
        std::move(callback).Run(value);
      });

  int32_t result_value = -1;
  ASSERT_TRUE(master_ptr_->Echo(456, &result_value));
  EXPECT_EQ(456, result_value);
}

// TODO(yzshen): Add more tests related to associated interfaces.

}  // namespace
}  // namespace test
}  // namespace mojo
