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

// Note: This file tests both binding.h (mojo::Binding) and strong_binding.h
// (mojo::StrongBinding).

#include "mojo/public/cpp/bindings/binding.h"

#include <stdint.h>
#include <utility>

#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h"
#include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h"
#include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace mojo {
namespace {

class BindingTestBase : public testing::Test {
 public:
  BindingTestBase() {}
  ~BindingTestBase() override {}

  base::MessageLoop& loop() { return loop_; }

 private:
  base::MessageLoop loop_;

  DISALLOW_COPY_AND_ASSIGN(BindingTestBase);
};

class ServiceImpl : public sample::Service {
 public:
  explicit ServiceImpl(bool* was_deleted = nullptr)
      : was_deleted_(was_deleted) {}
  ~ServiceImpl() override {
    if (was_deleted_)
      *was_deleted_ = true;
  }

 private:
  // sample::Service implementation
  void Frobinate(sample::FooPtr foo,
                 BazOptions options,
                 sample::PortPtr port,
                 const FrobinateCallback& callback) override {
    callback.Run(1);
  }
  void GetPort(InterfaceRequest<sample::Port> port) override {}

  bool* const was_deleted_;

  DISALLOW_COPY_AND_ASSIGN(ServiceImpl);
};

template <typename... Args>
void DoSetFlagAndRunClosure(bool* flag,
                            const base::Closure& closure,
                            Args... args) {
  *flag = true;
  if (!closure.is_null())
    closure.Run();
}

template <typename... Args>
base::Callback<void(Args...)> SetFlagAndRunClosure(
    bool* flag,
    const base::Closure& callback = base::Closure()) {
  return base::Bind(&DoSetFlagAndRunClosure<Args...>, flag, callback);
}

// BindingTest -----------------------------------------------------------------

using BindingTest = BindingTestBase;

TEST_F(BindingTest, Close) {
  bool called = false;
  sample::ServicePtr ptr;
  auto request = MakeRequest(&ptr);
  base::RunLoop run_loop;
  ptr.set_connection_error_handler(
      SetFlagAndRunClosure(&called, run_loop.QuitClosure()));
  ServiceImpl impl;
  Binding<sample::Service> binding(&impl, std::move(request));

  binding.Close();
  EXPECT_FALSE(called);
  run_loop.Run();
  EXPECT_TRUE(called);
}

// Tests that destroying a mojo::Binding closes the bound message pipe handle.
TEST_F(BindingTest, DestroyClosesMessagePipe) {
  bool encountered_error = false;
  ServiceImpl impl;
  sample::ServicePtr ptr;
  auto request = MakeRequest(&ptr);
  base::RunLoop run_loop;
  ptr.set_connection_error_handler(
      SetFlagAndRunClosure(&encountered_error, run_loop.QuitClosure()));
  bool called = false;
  base::RunLoop run_loop2;
  {
    Binding<sample::Service> binding(&impl, std::move(request));
    ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr,
                   SetFlagAndRunClosure<int32_t>(&called,
                                                 run_loop2.QuitClosure()));
    run_loop2.Run();
    EXPECT_TRUE(called);
    EXPECT_FALSE(encountered_error);
  }
  // Now that the Binding is out of scope we should detect an error on the other
  // end of the pipe.
  run_loop.Run();
  EXPECT_TRUE(encountered_error);

  // And calls should fail.
  called = false;
  ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr,
                 SetFlagAndRunClosure<int32_t>(&called,
                                               run_loop2.QuitClosure()));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(called);
}

// Tests that the binding's connection error handler gets called when the other
// end is closed.
TEST_F(BindingTest, ConnectionError) {
  bool called = false;
  {
    ServiceImpl impl;
    sample::ServicePtr ptr;
    Binding<sample::Service> binding(&impl, MakeRequest(&ptr));
    base::RunLoop run_loop;
    binding.set_connection_error_handler(
        SetFlagAndRunClosure(&called, run_loop.QuitClosure()));
    ptr.reset();
    EXPECT_FALSE(called);
    run_loop.Run();
    EXPECT_TRUE(called);
    // We want to make sure that it isn't called again during destruction.
    called = false;
  }
  EXPECT_FALSE(called);
}

// Tests that calling Close doesn't result in the connection error handler being
// called.
TEST_F(BindingTest, CloseDoesntCallConnectionErrorHandler) {
  ServiceImpl impl;
  sample::ServicePtr ptr;
  Binding<sample::Service> binding(&impl, MakeRequest(&ptr));
  bool called = false;
  binding.set_connection_error_handler(SetFlagAndRunClosure(&called));
  binding.Close();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(called);

  // We can also close the other end, and the error handler still won't be
  // called.
  ptr.reset();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(called);
}

class ServiceImplWithBinding : public ServiceImpl {
 public:
  ServiceImplWithBinding(bool* was_deleted,
                         const base::Closure& closure,
                         InterfaceRequest<sample::Service> request)
      : ServiceImpl(was_deleted),
        binding_(this, std::move(request)),
        closure_(closure) {
    binding_.set_connection_error_handler(
        base::Bind(&ServiceImplWithBinding::OnConnectionError,
                   base::Unretained(this)));
  }

 private:
  ~ServiceImplWithBinding() override{
    closure_.Run();
  }

  void OnConnectionError() { delete this; }

  Binding<sample::Service> binding_;
  base::Closure closure_;

  DISALLOW_COPY_AND_ASSIGN(ServiceImplWithBinding);
};

// Tests that the binding may be deleted in the connection error handler.
TEST_F(BindingTest, SelfDeleteOnConnectionError) {
  bool was_deleted = false;
  sample::ServicePtr ptr;
  // This should delete itself on connection error.
  base::RunLoop run_loop;
  new ServiceImplWithBinding(&was_deleted, run_loop.QuitClosure(),
                             MakeRequest(&ptr));
  ptr.reset();
  EXPECT_FALSE(was_deleted);
  run_loop.Run();
  EXPECT_TRUE(was_deleted);
}

// Tests that explicitly calling Unbind followed by rebinding works.
TEST_F(BindingTest, Unbind) {
  ServiceImpl impl;
  sample::ServicePtr ptr;
  Binding<sample::Service> binding(&impl, MakeRequest(&ptr));

  bool called = false;
  base::RunLoop run_loop;
  ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr,
                 SetFlagAndRunClosure<int32_t>(&called,
                                               run_loop.QuitClosure()));
  run_loop.Run();
  EXPECT_TRUE(called);

  called = false;
  auto request = binding.Unbind();
  EXPECT_FALSE(binding.is_bound());
  // All calls should fail when not bound...
  ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr,
                 SetFlagAndRunClosure<int32_t>(&called,
                                               run_loop.QuitClosure()));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(called);

  called = false;
  binding.Bind(std::move(request));
  EXPECT_TRUE(binding.is_bound());
  // ...and should succeed again when the rebound.
  base::RunLoop run_loop2;
  ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr,
                 SetFlagAndRunClosure<int32_t>(&called,
                                               run_loop2.QuitClosure()));
  run_loop2.Run();
  EXPECT_TRUE(called);
}

class IntegerAccessorImpl : public sample::IntegerAccessor {
 public:
  IntegerAccessorImpl() {}
  ~IntegerAccessorImpl() override {}

 private:
  // sample::IntegerAccessor implementation.
  void GetInteger(const GetIntegerCallback& callback) override {
    callback.Run(1, sample::Enum::VALUE);
  }
  void SetInteger(int64_t data, sample::Enum type) override {}

  DISALLOW_COPY_AND_ASSIGN(IntegerAccessorImpl);
};

TEST_F(BindingTest, SetInterfacePtrVersion) {
  IntegerAccessorImpl impl;
  sample::IntegerAccessorPtr ptr;
  Binding<sample::IntegerAccessor> binding(&impl, &ptr);
  EXPECT_EQ(3u, ptr.version());
}

TEST_F(BindingTest, PauseResume) {
  bool called = false;
  base::RunLoop run_loop;
  sample::ServicePtr ptr;
  auto request = MakeRequest(&ptr);
  ServiceImpl impl;
  Binding<sample::Service> binding(&impl, std::move(request));
  binding.PauseIncomingMethodCallProcessing();
  ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr,
                 SetFlagAndRunClosure<int32_t>(&called,
                                               run_loop.QuitClosure()));
  EXPECT_FALSE(called);
  base::RunLoop().RunUntilIdle();
  // Frobinate() should not be called as the binding is paused.
  EXPECT_FALSE(called);

  // Resume the binding, which should trigger processing.
  binding.ResumeIncomingMethodCallProcessing();
  run_loop.Run();
  EXPECT_TRUE(called);
}

// Verifies the connection error handler is not run while a binding is paused.
TEST_F(BindingTest, ErrorHandleNotRunWhilePaused) {
  bool called = false;
  base::RunLoop run_loop;
  sample::ServicePtr ptr;
  auto request = MakeRequest(&ptr);
  ServiceImpl impl;
  Binding<sample::Service> binding(&impl, std::move(request));
  binding.set_connection_error_handler(
      SetFlagAndRunClosure(&called, run_loop.QuitClosure()));
  binding.PauseIncomingMethodCallProcessing();

  ptr.reset();
  base::RunLoop().RunUntilIdle();
  // The connection error handle should not be called as the binding is paused.
  EXPECT_FALSE(called);

  // Resume the binding, which should trigger the error handler.
  binding.ResumeIncomingMethodCallProcessing();
  run_loop.Run();
  EXPECT_TRUE(called);
}

class PingServiceImpl : public test::PingService {
 public:
  PingServiceImpl() {}
  ~PingServiceImpl() override {}

  // test::PingService:
  void Ping(const PingCallback& callback) override {
    if (!ping_handler_.is_null())
      ping_handler_.Run();
    callback.Run();
  }

  void set_ping_handler(const base::Closure& handler) {
    ping_handler_ = handler;
  }

 private:
  base::Closure ping_handler_;

  DISALLOW_COPY_AND_ASSIGN(PingServiceImpl);
};

class CallbackFilter : public MessageReceiver {
 public:
  explicit CallbackFilter(const base::Closure& callback)
      : callback_(callback) {}
  ~CallbackFilter() override {}

  static std::unique_ptr<CallbackFilter> Wrap(const base::Closure& callback) {
    return base::MakeUnique<CallbackFilter>(callback);
  }

  // MessageReceiver:
  bool Accept(Message* message) override {
    callback_.Run();
    return true;
  }

 private:
  const base::Closure callback_;
};

// Verifies that message filters are notified in the order they were added and
// are always notified before a message is dispatched.
TEST_F(BindingTest, MessageFilter) {
  test::PingServicePtr ptr;
  PingServiceImpl impl;
  mojo::Binding<test::PingService> binding(&impl, MakeRequest(&ptr));

  int status = 0;
  auto handler_helper = [] (int* status, int expected_status, int new_status) {
    EXPECT_EQ(expected_status, *status);
    *status = new_status;
  };
  auto create_handler = [&] (int expected_status, int new_status) {
    return base::Bind(handler_helper, &status, expected_status, new_status);
  };

  binding.AddFilter(CallbackFilter::Wrap(create_handler(0, 1)));
  binding.AddFilter(CallbackFilter::Wrap(create_handler(1, 2)));
  impl.set_ping_handler(create_handler(2, 3));

  for (int i = 0; i < 10; ++i) {
    status = 0;
    base::RunLoop loop;
    ptr->Ping(loop.QuitClosure());
    loop.Run();
    EXPECT_EQ(3, status);
  }
}

void Fail() {
  FAIL() << "Unexpected connection error";
}

TEST_F(BindingTest, FlushForTesting) {
  bool called = false;
  sample::ServicePtr ptr;
  auto request = MakeRequest(&ptr);
  ServiceImpl impl;
  Binding<sample::Service> binding(&impl, std::move(request));
  binding.set_connection_error_handler(base::Bind(&Fail));

  ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr,
                 SetFlagAndRunClosure<int32_t>(&called));
  EXPECT_FALSE(called);
  // Because the flush is sent from the binding, it only guarantees that the
  // request has been received, not the response. The second flush waits for the
  // response to be received.
  binding.FlushForTesting();
  binding.FlushForTesting();
  EXPECT_TRUE(called);
}

TEST_F(BindingTest, FlushForTestingWithClosedPeer) {
  bool called = false;
  sample::ServicePtr ptr;
  auto request = MakeRequest(&ptr);
  ServiceImpl impl;
  Binding<sample::Service> binding(&impl, std::move(request));
  binding.set_connection_error_handler(SetFlagAndRunClosure(&called));
  ptr.reset();

  EXPECT_FALSE(called);
  binding.FlushForTesting();
  EXPECT_TRUE(called);
  binding.FlushForTesting();
}

TEST_F(BindingTest, ConnectionErrorWithReason) {
  sample::ServicePtr ptr;
  auto request = MakeRequest(&ptr);
  ServiceImpl impl;
  Binding<sample::Service> binding(&impl, std::move(request));

  base::RunLoop run_loop;
  binding.set_connection_error_with_reason_handler(base::Bind(
      [](const base::Closure& quit_closure, uint32_t custom_reason,
         const std::string& description) {
        EXPECT_EQ(1234u, custom_reason);
        EXPECT_EQ("hello", description);
        quit_closure.Run();
      },
      run_loop.QuitClosure()));

  ptr.ResetWithReason(1234u, "hello");

  run_loop.Run();
}

template <typename T>
struct WeakPtrImplRefTraits {
  using PointerType = base::WeakPtr<T>;

  static bool IsNull(const base::WeakPtr<T>& ptr) { return !ptr; }
  static T* GetRawPointer(base::WeakPtr<T>* ptr) { return ptr->get(); }
};

template <typename T>
using WeakBinding = Binding<T, WeakPtrImplRefTraits<T>>;

TEST_F(BindingTest, CustomImplPointerType) {
  PingServiceImpl impl;
  base::WeakPtrFactory<test::PingService> weak_factory(&impl);

  test::PingServicePtr proxy;
  WeakBinding<test::PingService> binding(weak_factory.GetWeakPtr(),
                                         MakeRequest(&proxy));

  {
    // Ensure the binding is functioning.
    base::RunLoop run_loop;
    proxy->Ping(run_loop.QuitClosure());
    run_loop.Run();
  }

  {
    // Attempt to dispatch another message after the WeakPtr is invalidated.
    base::Closure assert_not_reached = base::Bind([] { NOTREACHED(); });
    impl.set_ping_handler(assert_not_reached);
    proxy->Ping(assert_not_reached);

    // The binding will close its end of the pipe which will trigger a
    // connection error on |proxy|.
    base::RunLoop run_loop;
    proxy.set_connection_error_handler(run_loop.QuitClosure());
    weak_factory.InvalidateWeakPtrs();
    run_loop.Run();
  }
}

// StrongBindingTest -----------------------------------------------------------

using StrongBindingTest = BindingTestBase;

// Tests that destroying a mojo::StrongBinding closes the bound message pipe
// handle but does *not* destroy the implementation object.
TEST_F(StrongBindingTest, DestroyClosesMessagePipe) {
  base::RunLoop run_loop;
  bool encountered_error = false;
  bool was_deleted = false;
  sample::ServicePtr ptr;
  auto request = MakeRequest(&ptr);
  ptr.set_connection_error_handler(
      SetFlagAndRunClosure(&encountered_error, run_loop.QuitClosure()));
  bool called = false;
  base::RunLoop run_loop2;

  auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted),
                                   std::move(request));
  ptr->Frobinate(
      nullptr, sample::Service::BazOptions::REGULAR, nullptr,
      SetFlagAndRunClosure<int32_t>(&called, run_loop2.QuitClosure()));
  run_loop2.Run();
  EXPECT_TRUE(called);
  EXPECT_FALSE(encountered_error);
  binding->Close();

  // Now that the StrongBinding is closed we should detect an error on the other
  // end of the pipe.
  run_loop.Run();
  EXPECT_TRUE(encountered_error);

  // Destroying the StrongBinding also destroys the impl.
  ASSERT_TRUE(was_deleted);
}

// Tests the typical case, where the implementation object owns the
// StrongBinding (and should be destroyed on connection error).
TEST_F(StrongBindingTest, ConnectionErrorDestroysImpl) {
  sample::ServicePtr ptr;
  bool was_deleted = false;
  // Will delete itself.
  base::RunLoop run_loop;
  new ServiceImplWithBinding(&was_deleted, run_loop.QuitClosure(),
                             MakeRequest(&ptr));

  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(was_deleted);

  ptr.reset();
  EXPECT_FALSE(was_deleted);
  run_loop.Run();
  EXPECT_TRUE(was_deleted);
}

TEST_F(StrongBindingTest, FlushForTesting) {
  bool called = false;
  bool was_deleted = false;
  sample::ServicePtr ptr;
  auto request = MakeRequest(&ptr);
  auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted),
                                   std::move(request));
  binding->set_connection_error_handler(base::Bind(&Fail));

  ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr,
                 SetFlagAndRunClosure<int32_t>(&called));
  EXPECT_FALSE(called);
  // Because the flush is sent from the binding, it only guarantees that the
  // request has been received, not the response. The second flush waits for the
  // response to be received.
  ASSERT_TRUE(binding);
  binding->FlushForTesting();
  ASSERT_TRUE(binding);
  binding->FlushForTesting();
  EXPECT_TRUE(called);
  EXPECT_FALSE(was_deleted);
  ptr.reset();
  ASSERT_TRUE(binding);
  binding->set_connection_error_handler(base::Closure());
  binding->FlushForTesting();
  EXPECT_TRUE(was_deleted);
}

TEST_F(StrongBindingTest, FlushForTestingWithClosedPeer) {
  bool called = false;
  bool was_deleted = false;
  sample::ServicePtr ptr;
  auto request = MakeRequest(&ptr);
  auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted),
                                   std::move(request));
  binding->set_connection_error_handler(SetFlagAndRunClosure(&called));
  ptr.reset();

  EXPECT_FALSE(called);
  EXPECT_FALSE(was_deleted);
  ASSERT_TRUE(binding);
  binding->FlushForTesting();
  EXPECT_TRUE(called);
  EXPECT_TRUE(was_deleted);
  ASSERT_FALSE(binding);
}

TEST_F(StrongBindingTest, ConnectionErrorWithReason) {
  sample::ServicePtr ptr;
  auto request = MakeRequest(&ptr);
  auto binding =
      MakeStrongBinding(base::MakeUnique<ServiceImpl>(), std::move(request));
  base::RunLoop run_loop;
  binding->set_connection_error_with_reason_handler(base::Bind(
      [](const base::Closure& quit_closure, uint32_t custom_reason,
         const std::string& description) {
        EXPECT_EQ(5678u, custom_reason);
        EXPECT_EQ("hello", description);
        quit_closure.Run();
      },
      run_loop.QuitClosure()));

  ptr.ResetWithReason(5678u, "hello");

  run_loop.Run();
}

}  // namespace
}  // mojo
