// Copyright 2013 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/ref_counted.h"
#include "base/run_loop.h"
#include "dbus/bus.h"
#include "dbus/object_proxy.h"
#include "dbus/test_service.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace dbus {
namespace {

class ObjectProxyTest : public testing::Test {
 protected:
  void SetUp() override {
    Bus::Options bus_options;
    bus_options.bus_type = Bus::SESSION;
    bus_options.connection_type = Bus::PRIVATE;
    bus_ = new Bus(bus_options);
  }

  void TearDown() override { bus_->ShutdownAndBlock(); }

  base::MessageLoopForIO message_loop_;
  scoped_refptr<Bus> bus_;
};

// Used as a WaitForServiceToBeAvailableCallback.
void OnServiceIsAvailable(bool* dest_service_is_available,
                          int* num_calls,
                          bool src_service_is_available) {
  *dest_service_is_available = src_service_is_available;
  (*num_calls)++;
}

// Used as a callback for TestService::RequestOwnership().
void OnOwnershipRequestDone(bool success) {
  ASSERT_TRUE(success);
}

// Used as a callback for TestService::ReleaseOwnership().
void OnOwnershipReleased() {}

TEST_F(ObjectProxyTest, WaitForServiceToBeAvailableRunOnce) {
  TestService::Options options;
  TestService test_service(options);
  ObjectProxy* object_proxy = bus_->GetObjectProxy(
      test_service.service_name(), ObjectPath("/org/chromium/TestObject"));

  // The callback is not yet called because the service is not available.
  int num_calls = 0;
  bool service_is_available = false;
  object_proxy->WaitForServiceToBeAvailable(
      base::Bind(&OnServiceIsAvailable, &service_is_available, &num_calls));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, num_calls);

  // Start the service. The callback should be called asynchronously.
  ASSERT_TRUE(test_service.StartService());
  ASSERT_TRUE(test_service.WaitUntilServiceIsStarted());
  ASSERT_TRUE(test_service.has_ownership());
  num_calls = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, num_calls);
  EXPECT_TRUE(service_is_available);

  // Release the service's ownership of its name. The callback should not be
  // invoked again.
  test_service.ReleaseOwnership(base::Bind(&OnOwnershipReleased));
  num_calls = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, num_calls);

  // Take ownership of the name and check that the callback is not called.
  test_service.RequestOwnership(base::Bind(&OnOwnershipRequestDone));
  num_calls = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, num_calls);
}

TEST_F(ObjectProxyTest, WaitForServiceToBeAvailableAlreadyRunning) {
  TestService::Options options;
  TestService test_service(options);
  ObjectProxy* object_proxy = bus_->GetObjectProxy(
      test_service.service_name(), ObjectPath("/org/chromium/TestObject"));

  ASSERT_TRUE(test_service.StartService());
  ASSERT_TRUE(test_service.WaitUntilServiceIsStarted());
  ASSERT_TRUE(test_service.has_ownership());

  // Since the service is already running, the callback should be invoked
  // immediately (but asynchronously, rather than the callback being invoked
  // directly within WaitForServiceToBeAvailable()).
  int num_calls = 0;
  bool service_is_available = false;
  object_proxy->WaitForServiceToBeAvailable(
      base::Bind(&OnServiceIsAvailable, &service_is_available, &num_calls));
  EXPECT_EQ(0, num_calls);

  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, num_calls);
  EXPECT_TRUE(service_is_available);
}

TEST_F(ObjectProxyTest, WaitForServiceToBeAvailableMultipleCallbacks) {
  TestService::Options options;
  TestService test_service(options);
  ObjectProxy* object_proxy = bus_->GetObjectProxy(
      test_service.service_name(), ObjectPath("/org/chromium/TestObject"));

  // Register two callbacks.
  int num_calls_1 = 0, num_calls_2 = 0;
  bool service_is_available_1 = false, service_is_available_2 = false;
  object_proxy->WaitForServiceToBeAvailable(
      base::Bind(&OnServiceIsAvailable, &service_is_available_1, &num_calls_1));
  object_proxy->WaitForServiceToBeAvailable(
      base::Bind(&OnServiceIsAvailable, &service_is_available_2, &num_calls_2));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, num_calls_1);
  EXPECT_EQ(0, num_calls_2);

  // Start the service and confirm that both callbacks are invoked.
  ASSERT_TRUE(test_service.StartService());
  ASSERT_TRUE(test_service.WaitUntilServiceIsStarted());
  ASSERT_TRUE(test_service.has_ownership());
  num_calls_1 = 0;
  num_calls_2 = 0;
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, num_calls_1);
  EXPECT_EQ(1, num_calls_2);
  EXPECT_TRUE(service_is_available_1);
  EXPECT_TRUE(service_is_available_2);
}

}  // namespace
}  // namespace dbus
