// Copyright (c) 2012 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/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_samples.h"
#include "base/metrics/statistics_recorder.h"
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_restrictions.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_proxy.h"
#include "dbus/test_service.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace dbus {

// The test for sender verification in ObjectProxy.
class SignalSenderVerificationTest : public testing::Test {
 public:
  SignalSenderVerificationTest()
      : on_name_owner_changed_called_(false),
        on_ownership_called_(false) {
  }

  virtual void SetUp() {
    base::StatisticsRecorder::Initialize();

    // Make the main thread not to allow IO.
    base::ThreadRestrictions::SetIOAllowed(false);

    // Start the D-Bus thread.
    dbus_thread_.reset(new base::Thread("D-Bus Thread"));
    base::Thread::Options thread_options;
    thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
    ASSERT_TRUE(dbus_thread_->StartWithOptions(thread_options));

    // Create the client, using the D-Bus thread.
    Bus::Options bus_options;
    bus_options.bus_type = Bus::SESSION;
    bus_options.connection_type = Bus::PRIVATE;
    bus_options.dbus_task_runner = dbus_thread_->message_loop_proxy();
    bus_ = new Bus(bus_options);
    object_proxy_ = bus_->GetObjectProxy(
        "org.chromium.TestService",
        ObjectPath("/org/chromium/TestObject"));
    ASSERT_TRUE(bus_->HasDBusThread());

    object_proxy_->SetNameOwnerChangedCallback(
        base::Bind(&SignalSenderVerificationTest::OnNameOwnerChanged,
                   base::Unretained(this),
                   &on_name_owner_changed_called_));

    // Connect to the "Test" signal of "org.chromium.TestInterface" from
    // the remote object.
    object_proxy_->ConnectToSignal(
        "org.chromium.TestInterface",
        "Test",
        base::Bind(&SignalSenderVerificationTest::OnTestSignal,
                   base::Unretained(this)),
        base::Bind(&SignalSenderVerificationTest::OnConnected,
                   base::Unretained(this)));
    // Wait until the object proxy is connected to the signal.
    message_loop_.Run();

    // Start the test service, using the D-Bus thread.
    TestService::Options options;
    options.dbus_task_runner = dbus_thread_->message_loop_proxy();
    test_service_.reset(new TestService(options));
    ASSERT_TRUE(test_service_->StartService());
    ASSERT_TRUE(test_service_->WaitUntilServiceIsStarted());
    ASSERT_TRUE(test_service_->HasDBusThread());
    ASSERT_TRUE(test_service_->has_ownership());

    // Same setup for the second TestService. This service should not have the
    // ownership of the name at this point.
    test_service2_.reset(new TestService(options));
    ASSERT_TRUE(test_service2_->StartService());
    ASSERT_TRUE(test_service2_->WaitUntilServiceIsStarted());
    ASSERT_TRUE(test_service2_->HasDBusThread());
    ASSERT_FALSE(test_service2_->has_ownership());

    // The name should be owned and known at this point.
    if (!on_name_owner_changed_called_)
      message_loop_.Run();
    ASSERT_FALSE(latest_name_owner_.empty());
  }

  virtual void TearDown() {
    bus_->ShutdownOnDBusThreadAndBlock();

    // Shut down the service.
    test_service_->ShutdownAndBlock();
    test_service2_->ShutdownAndBlock();

    // Reset to the default.
    base::ThreadRestrictions::SetIOAllowed(true);

    // Stopping a thread is considered an IO operation, so do this after
    // allowing IO.
    test_service_->Stop();
    test_service2_->Stop();
  }

  void OnOwnership(bool expected, bool success) {
    ASSERT_EQ(expected, success);
    // PostTask to quit the MessageLoop as this is called from D-Bus thread.
    message_loop_.PostTask(
        FROM_HERE,
        base::Bind(&SignalSenderVerificationTest::OnOwnershipInternal,
                   base::Unretained(this)));
  }

  void OnOwnershipInternal() {
    on_ownership_called_ = true;
    message_loop_.Quit();
  }

  void OnNameOwnerChanged(bool* called_flag, Signal* signal) {
    MessageReader reader(signal);
    std::string name, old_owner, new_owner;
    ASSERT_TRUE(reader.PopString(&name));
    ASSERT_TRUE(reader.PopString(&old_owner));
    ASSERT_TRUE(reader.PopString(&new_owner));
    latest_name_owner_ = new_owner;
    *called_flag = true;
    message_loop_.Quit();
  }

  // Called when the "Test" signal is received, in the main thread.
  // Copy the string payload to |test_signal_string_|.
  void OnTestSignal(Signal* signal) {
    MessageReader reader(signal);
    ASSERT_TRUE(reader.PopString(&test_signal_string_));
    message_loop_.Quit();
  }

  // Called when connected to the signal.
  void OnConnected(const std::string& interface_name,
                   const std::string& signal_name,
                   bool success) {
    ASSERT_TRUE(success);
    message_loop_.Quit();
  }

 protected:
  // Wait for the hey signal to be received.
  void WaitForTestSignal() {
    // OnTestSignal() will quit the message loop.
    message_loop_.Run();
  }

  // Stopping a thread is considered an IO operation, so we need to fiddle with
  // thread restrictions before and after calling Stop() on a TestService.
  void SafeServiceStop(TestService* test_service) {
    base::ThreadRestrictions::SetIOAllowed(true);
    test_service->Stop();
    base::ThreadRestrictions::SetIOAllowed(false);
  }

  base::MessageLoop message_loop_;
  scoped_ptr<base::Thread> dbus_thread_;
  scoped_refptr<Bus> bus_;
  ObjectProxy* object_proxy_;
  scoped_ptr<TestService> test_service_;
  scoped_ptr<TestService> test_service2_;
  // Text message from "Test" signal.
  std::string test_signal_string_;

  // The known latest name owner of TestService. Updated in OnNameOwnerChanged.
  std::string latest_name_owner_;

  // Boolean flags to record callback calls.
  bool on_name_owner_changed_called_;
  bool on_ownership_called_;
};

TEST_F(SignalSenderVerificationTest, TestSignalAccepted) {
  const char kMessage[] = "hello, world";
  // Send the test signal from the exported object.
  test_service_->SendTestSignal(kMessage);
  // Receive the signal with the object proxy. The signal is handled in
  // SignalSenderVerificationTest::OnTestSignal() in the main thread.
  WaitForTestSignal();
  ASSERT_EQ(kMessage, test_signal_string_);
}

TEST_F(SignalSenderVerificationTest, TestSignalRejected) {
  // To make sure the histogram instance is created.
  UMA_HISTOGRAM_COUNTS("DBus.RejectedSignalCount", 0);
  base::HistogramBase* reject_signal_histogram =
        base::StatisticsRecorder::FindHistogram("DBus.RejectedSignalCount");
  scoped_ptr<base::HistogramSamples> samples1(
      reject_signal_histogram->SnapshotSamples());

  const char kNewMessage[] = "hello, new world";
  test_service2_->SendTestSignal(kNewMessage);

  // This test tests that our callback is NOT called by the ObjectProxy.
  // Sleep to have message delivered to the client via the D-Bus service.
  base::PlatformThread::Sleep(TestTimeouts::action_timeout());

  scoped_ptr<base::HistogramSamples> samples2(
      reject_signal_histogram->SnapshotSamples());

  ASSERT_EQ("", test_signal_string_);
  EXPECT_EQ(samples1->TotalCount() + 1, samples2->TotalCount());
}

TEST_F(SignalSenderVerificationTest, TestOwnerChanged) {
  const char kMessage[] = "hello, world";

  // Send the test signal from the exported object.
  test_service_->SendTestSignal(kMessage);
  // Receive the signal with the object proxy. The signal is handled in
  // SignalSenderVerificationTest::OnTestSignal() in the main thread.
  WaitForTestSignal();
  ASSERT_EQ(kMessage, test_signal_string_);

  // Release and acquire the name ownership.
  // latest_name_owner_ should be non empty as |test_service_| owns the name.
  ASSERT_FALSE(latest_name_owner_.empty());
  test_service_->ShutdownAndBlock();
  // OnNameOwnerChanged will PostTask to quit the message loop.
  message_loop_.Run();
  // latest_name_owner_ should be empty as the owner is gone.
  ASSERT_TRUE(latest_name_owner_.empty());

  // Reset the flag as NameOwnerChanged is already received in setup.
  on_name_owner_changed_called_ = false;
  on_ownership_called_ = false;
  test_service2_->RequestOwnership(
      base::Bind(&SignalSenderVerificationTest::OnOwnership,
                 base::Unretained(this), true));
  // Both of OnNameOwnerChanged() and OnOwnership() should quit the MessageLoop,
  // but there's no expected order of those 2 event.
  message_loop_.Run();
  if (!on_name_owner_changed_called_ || !on_ownership_called_)
    message_loop_.Run();
  ASSERT_TRUE(on_name_owner_changed_called_);
  ASSERT_TRUE(on_ownership_called_);

  // latest_name_owner_ becomes non empty as the new owner appears.
  ASSERT_FALSE(latest_name_owner_.empty());

  // Now the second service owns the name.
  const char kNewMessage[] = "hello, new world";

  test_service2_->SendTestSignal(kNewMessage);
  WaitForTestSignal();
  ASSERT_EQ(kNewMessage, test_signal_string_);
}

TEST_F(SignalSenderVerificationTest, TestOwnerStealing) {
  // Release and acquire the name ownership.
  // latest_name_owner_ should be non empty as |test_service_| owns the name.
  ASSERT_FALSE(latest_name_owner_.empty());
  test_service_->ShutdownAndBlock();
  // OnNameOwnerChanged will PostTask to quit the message loop.
  message_loop_.Run();
  // latest_name_owner_ should be empty as the owner is gone.
  ASSERT_TRUE(latest_name_owner_.empty());
  // Reset the flag as NameOwnerChanged is already received in setup.
  on_name_owner_changed_called_ = false;

  // Start a test service that allows theft, using the D-Bus thread.
  TestService::Options options;
  options.dbus_task_runner = dbus_thread_->message_loop_proxy();
  options.request_ownership_options = Bus::REQUIRE_PRIMARY_ALLOW_REPLACEMENT;
  TestService stealable_test_service(options);
  ASSERT_TRUE(stealable_test_service.StartService());
  ASSERT_TRUE(stealable_test_service.WaitUntilServiceIsStarted());
  ASSERT_TRUE(stealable_test_service.HasDBusThread());
  ASSERT_TRUE(stealable_test_service.has_ownership());

  // OnNameOwnerChanged will PostTask to quit the message loop.
  message_loop_.Run();

  // Send a signal to check that the service is correctly owned.
  const char kMessage[] = "hello, world";

  // Send the test signal from the exported object.
  stealable_test_service.SendTestSignal(kMessage);
  // Receive the signal with the object proxy. The signal is handled in
  // SignalSenderVerificationTest::OnTestSignal() in the main thread.
  WaitForTestSignal();
  ASSERT_EQ(kMessage, test_signal_string_);

  // Reset the flag as NameOwnerChanged was called above.
  on_name_owner_changed_called_ = false;
  test_service2_->RequestOwnership(
      base::Bind(&SignalSenderVerificationTest::OnOwnership,
                 base::Unretained(this), true));
  // Both of OnNameOwnerChanged() and OnOwnership() should quit the MessageLoop,
  // but there's no expected order of those 2 event.
  message_loop_.Run();
  if (!on_name_owner_changed_called_ || !on_ownership_called_)
    message_loop_.Run();
  ASSERT_TRUE(on_name_owner_changed_called_);
  ASSERT_TRUE(on_ownership_called_);

  // Now the second service owns the name.
  const char kNewMessage[] = "hello, new world";

  test_service2_->SendTestSignal(kNewMessage);
  WaitForTestSignal();
  ASSERT_EQ(kNewMessage, test_signal_string_);

  SafeServiceStop(&stealable_test_service);
}

// Fails on Linux ChromiumOS Tests
TEST_F(SignalSenderVerificationTest, DISABLED_TestMultipleObjects) {
  const char kMessage[] = "hello, world";

  ObjectProxy* object_proxy2 = bus_->GetObjectProxy(
      "org.chromium.TestService",
      ObjectPath("/org/chromium/DifferentObject"));

  bool second_name_owner_changed_called = false;
  object_proxy2->SetNameOwnerChangedCallback(
      base::Bind(&SignalSenderVerificationTest::OnNameOwnerChanged,
                 base::Unretained(this),
                 &second_name_owner_changed_called));

  // Connect to a signal on the additional remote object to trigger the
  // name owner matching.
  object_proxy2->ConnectToSignal(
      "org.chromium.DifferentTestInterface",
      "Test",
      base::Bind(&SignalSenderVerificationTest::OnTestSignal,
                 base::Unretained(this)),
      base::Bind(&SignalSenderVerificationTest::OnConnected,
                 base::Unretained(this)));
  // Wait until the object proxy is connected to the signal.
  message_loop_.Run();

  // Send the test signal from the exported object.
  test_service_->SendTestSignal(kMessage);
  // Receive the signal with the object proxy. The signal is handled in
  // SignalSenderVerificationTest::OnTestSignal() in the main thread.
  WaitForTestSignal();
  ASSERT_EQ(kMessage, test_signal_string_);

  // Release and acquire the name ownership.
  // latest_name_owner_ should be non empty as |test_service_| owns the name.
  ASSERT_FALSE(latest_name_owner_.empty());
  test_service_->ShutdownAndBlock();
  // OnNameOwnerChanged will PostTask to quit the message loop.
  message_loop_.Run();
  // latest_name_owner_ should be empty as the owner is gone.
  ASSERT_TRUE(latest_name_owner_.empty());

  // Reset the flag as NameOwnerChanged is already received in setup.
  on_name_owner_changed_called_ = false;
  second_name_owner_changed_called = false;
  test_service2_->RequestOwnership(
      base::Bind(&SignalSenderVerificationTest::OnOwnership,
                 base::Unretained(this), true));
  // Both of OnNameOwnerChanged() and OnOwnership() should quit the MessageLoop,
  // but there's no expected order of those 2 event.
  while (!on_name_owner_changed_called_ || !second_name_owner_changed_called ||
         !on_ownership_called_)
    message_loop_.Run();
  ASSERT_TRUE(on_name_owner_changed_called_);
  ASSERT_TRUE(second_name_owner_changed_called);
  ASSERT_TRUE(on_ownership_called_);

  // latest_name_owner_ becomes non empty as the new owner appears.
  ASSERT_FALSE(latest_name_owner_.empty());

  // Now the second service owns the name.
  const char kNewMessage[] = "hello, new world";

  test_service2_->SendTestSignal(kNewMessage);
  WaitForTestSignal();
  ASSERT_EQ(kNewMessage, test_signal_string_);
}

}  // namespace dbus
