// 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 "build/build_config.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
#include "mojo/public/cpp/bindings/string.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "mojo/public/cpp/utility/run_loop.h"
#include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"

///////////////////////////////////////////////////////////////////////////////
//
// The tests in this file are designed to test the interaction between a
// Callback and its associated Binding. If a Callback is deleted before
// being used we DCHECK fail--unless the associated Binding has already
// been closed or deleted. This contract must be explained to the Mojo
// application developer. For example it is the developer's responsibility to
// ensure that the Binding is destroyed before an unused Callback is destroyed.
//
///////////////////////////////////////////////////////////////////////////////

namespace mojo {
namespace test {
namespace {

// A Runnable object that saves the last value it sees via the
// provided int32_t*. Used on the client side.
class ValueSaver {
 public:
  explicit ValueSaver(int32_t* last_value_seen)
      : last_value_seen_(last_value_seen) {}
  void Run(int32_t x) const { *last_value_seen_ = x; }

 private:
  int32_t* const last_value_seen_;
};

// An implementation of sample::Provider used on the server side.
// It only implements one of the methods: EchoInt().
// All it does is save the values and Callbacks it sees.
class InterfaceImpl : public sample::Provider {
 public:
  InterfaceImpl()
      : last_server_value_seen_(0),
        callback_saved_(new Callback<void(int32_t)>()) {}

  ~InterfaceImpl() override {
    if (callback_saved_) {
      delete callback_saved_;
    }
  }

  // Run's the callback previously saved from the last invocation
  // of |EchoInt()|.
  bool RunCallback() {
    if (callback_saved_) {
      callback_saved_->Run(last_server_value_seen_);
      return true;
    }
    return false;
  }

  // Delete's the previously saved callback.
  void DeleteCallback() {
    delete callback_saved_;
    callback_saved_ = nullptr;
  }

  // sample::Provider implementation

  // Saves its two input values in member variables and does nothing else.
  void EchoInt(int32_t x, const Callback<void(int32_t)>& callback) override {
    last_server_value_seen_ = x;
    *callback_saved_ = callback;
  }

  void EchoString(const String& a,
                  const Callback<void(String)>& callback) override {
    MOJO_CHECK(false) << "Not implemented.";
  }

  void EchoStrings(const String& a,
                   const String& b,
                   const Callback<void(String, String)>& callback) override {
    MOJO_CHECK(false) << "Not implemented.";
  }

  void EchoMessagePipeHandle(
      ScopedMessagePipeHandle a,
      const Callback<void(ScopedMessagePipeHandle)>& callback) override {
    MOJO_CHECK(false) << "Not implemented.";
  }

  void EchoEnum(sample::Enum a,
                const Callback<void(sample::Enum)>& callback) override {
    MOJO_CHECK(false) << "Not implemented.";
  }

  void resetLastServerValueSeen() { last_server_value_seen_ = 0; }

  int32_t last_server_value_seen() const { return last_server_value_seen_; }

 private:
  int32_t last_server_value_seen_;
  Callback<void(int32_t)>* callback_saved_;
};

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

 protected:
  int32_t last_client_callback_value_seen_;
  sample::ProviderPtr interface_ptr_;

  void PumpMessages() { loop_.RunUntilIdle(); }

 private:
  RunLoop loop_;
};

// Tests that the InterfacePtr and the Binding can communicate with each
// other normally.
TEST_F(BindingCallbackTest, Basic) {
  // Create the ServerImpl and the Binding.
  InterfaceImpl server_impl;
  Binding<sample::Provider> binding(&server_impl, GetProxy(&interface_ptr_));

  // Initialize the test values.
  server_impl.resetLastServerValueSeen();
  last_client_callback_value_seen_ = 0;

  // Invoke the Echo method.
  interface_ptr_->EchoInt(7, ValueSaver(&last_client_callback_value_seen_));
  PumpMessages();

  // Check that server saw the correct value, but the client has not yet.
  EXPECT_EQ(7, server_impl.last_server_value_seen());
  EXPECT_EQ(0, last_client_callback_value_seen_);

  // Now run the Callback.
  server_impl.RunCallback();
  PumpMessages();

  // Check that the client has now seen the correct value.
  EXPECT_EQ(7, last_client_callback_value_seen_);

  // Initialize the test values again.
  server_impl.resetLastServerValueSeen();
  last_client_callback_value_seen_ = 0;

  // Invoke the Echo method again.
  interface_ptr_->EchoInt(13, ValueSaver(&last_client_callback_value_seen_));
  PumpMessages();

  // Check that server saw the correct value, but the client has not yet.
  EXPECT_EQ(13, server_impl.last_server_value_seen());
  EXPECT_EQ(0, last_client_callback_value_seen_);

  // Now run the Callback again.
  server_impl.RunCallback();
  PumpMessages();

  // Check that the client has now seen the correct value again.
  EXPECT_EQ(13, last_client_callback_value_seen_);
}

// Tests that running the Callback after the Binding has been deleted
// results in a clean failure.
TEST_F(BindingCallbackTest, DeleteBindingThenRunCallback) {
  // Create the ServerImpl.
  InterfaceImpl server_impl;
  {
    // Create the binding in an inner scope so it can be deleted first.
    Binding<sample::Provider> binding(&server_impl, GetProxy(&interface_ptr_));

    // Initialize the test values.
    server_impl.resetLastServerValueSeen();
    last_client_callback_value_seen_ = 0;

    // Invoke the Echo method.
    interface_ptr_->EchoInt(7, ValueSaver(&last_client_callback_value_seen_));
    PumpMessages();
  }
  // The binding has now been destroyed and the pipe is closed.

  // Check that server saw the correct value, but the client has not yet.
  EXPECT_EQ(7, server_impl.last_server_value_seen());
  EXPECT_EQ(0, last_client_callback_value_seen_);

  // Now try to run the Callback. This should do nothing since the pipe
  // is closed.
  EXPECT_TRUE(server_impl.RunCallback());
  PumpMessages();

  // Check that the client has still not seen the correct value.
  EXPECT_EQ(0, last_client_callback_value_seen_);

  // Attempt to invoke the method again and confirm that an error was
  // encountered.
  interface_ptr_->EchoInt(13, ValueSaver(&last_client_callback_value_seen_));
  PumpMessages();
  EXPECT_TRUE(interface_ptr_.encountered_error());
}

// Tests that deleting a Callback without running it after the corresponding
// binding has already been deleted does not result in a crash.
TEST_F(BindingCallbackTest, DeleteBindingThenDeleteCallback) {
  // Create the ServerImpl.
  InterfaceImpl server_impl;
  {
    // Create the binding in an inner scope so it can be deleted first.
    Binding<sample::Provider> binding(&server_impl, GetProxy(&interface_ptr_));

    // Initialize the test values.
    server_impl.resetLastServerValueSeen();
    last_client_callback_value_seen_ = 0;

    // Invoke the Echo method.
    interface_ptr_->EchoInt(7, ValueSaver(&last_client_callback_value_seen_));
    PumpMessages();
  }
  // The binding has now been destroyed and the pipe is closed.

  // Check that server saw the correct value, but the client has not yet.
  EXPECT_EQ(7, server_impl.last_server_value_seen());
  EXPECT_EQ(0, last_client_callback_value_seen_);

  // Delete the callback without running it. This should not
  // cause a problem because the insfrastructure can detect that the
  // binding has already been destroyed and the pipe is closed.
  server_impl.DeleteCallback();
}

// Tests that closing a Binding allows us to delete a callback
// without running it without encountering a crash.
TEST_F(BindingCallbackTest, CloseBindingBeforeDeletingCallback) {
  // Create the ServerImpl and the Binding.
  InterfaceImpl server_impl;
  Binding<sample::Provider> binding(&server_impl, GetProxy(&interface_ptr_));

  // Initialize the test values.
  server_impl.resetLastServerValueSeen();
  last_client_callback_value_seen_ = 0;

  // Invoke the Echo method.
  interface_ptr_->EchoInt(7, ValueSaver(&last_client_callback_value_seen_));
  PumpMessages();

  // Check that server saw the correct value, but the client has not yet.
  EXPECT_EQ(7, server_impl.last_server_value_seen());
  EXPECT_EQ(0, last_client_callback_value_seen_);

  // Now close the Binding.
  binding.Close();

  // Delete the callback without running it. This should not
  // cause a crash because the insfrastructure can detect that the
  // binding has already been closed.
  server_impl.DeleteCallback();

  // Check that the client has still not seen the correct value.
  EXPECT_EQ(0, last_client_callback_value_seen_);
}

// Tests that deleting a Callback without using it before the
// Binding has been destroyed or closed results in a DCHECK.
TEST_F(BindingCallbackTest, DeleteCallbackBeforeBindingDeathTest) {
  // Create the ServerImpl and the Binding.
  InterfaceImpl server_impl;
  Binding<sample::Provider> binding(&server_impl, GetProxy(&interface_ptr_));

  // Initialize the test values.
  server_impl.resetLastServerValueSeen();
  last_client_callback_value_seen_ = 0;

  // Invoke the Echo method.
  interface_ptr_->EchoInt(7, ValueSaver(&last_client_callback_value_seen_));
  PumpMessages();

  // Check that server saw the correct value, but the client has not yet.
  EXPECT_EQ(7, server_impl.last_server_value_seen());
  EXPECT_EQ(0, last_client_callback_value_seen_);

#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
  // Delete the callback without running it. This should cause a crash in debug
  // builds due to a DCHECK.
  EXPECT_DEATH_IF_SUPPORTED(server_impl.DeleteCallback(),
                            "Check failed: !callback_was_dropped.");
#endif
}

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