// Copyright 2018 The Chromium OS 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 <memory>

#include <base/bind.h>
#include <base/message_loop/message_loop.h>
#include <base/run_loop.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_object_manager.h>
#include <dbus/mock_object_proxy.h>
#include <dbus/property.h>
#include <gtest/gtest.h>

#include "bluetooth/dispatcher/mock_object_manager_interface_multiplexer.h"

using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Mock;
using ::testing::Return;

namespace bluetooth {

namespace {

constexpr char kTestServiceName1[] = "org.example.Service1";
constexpr char kTestServiceName2[] = "org.example.Service2";
constexpr char kTestInterfaceName[] = "org.example.Interface";
constexpr char kTestRootServicePath[] = "/org/example/Root";

}  // namespace

class ObjectManagerInterfaceMultiplexerTest : public ::testing::Test {
 public:
  void SetUp() override {
    bus_ = new dbus::MockBus(dbus::Bus::Options());
    EXPECT_CALL(*bus_, GetDBusTaskRunner())
        .WillRepeatedly(Return(message_loop_.task_runner().get()));
    EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber());
    EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber());
    // For this test purposes it's okay to mock dbus::Bus::Connect() to return
    // false. This will make MockObjectManager fail its initialization but we
    // don't care about it in this test.
    EXPECT_CALL(*bus_, Connect()).WillRepeatedly(Return(false));

    dbus::ObjectPath root_service_path(kTestRootServicePath);
    object_proxy1_ = new dbus::MockObjectProxy(bus_.get(), kTestServiceName1,
                                               root_service_path);
    object_proxy2_ = new dbus::MockObjectProxy(bus_.get(), kTestServiceName2,
                                               root_service_path);
    EXPECT_CALL(*bus_, GetObjectProxy(kTestServiceName1, root_service_path))
        .WillOnce(Return(object_proxy1_.get()));
    EXPECT_CALL(*bus_, GetObjectProxy(kTestServiceName2, root_service_path))
        .WillOnce(Return(object_proxy2_.get()));
    object_manager1_ = new dbus::MockObjectManager(
        bus_.get(), kTestServiceName1, root_service_path);
    object_manager2_ = new dbus::MockObjectManager(
        bus_.get(), kTestServiceName2, root_service_path);
    // Force MessageLoop to run all pending tasks as an effect of instantiating
    // MockObjectManager. This is needed to avoid memory leak as pending tasks
    // hold pointers.
    base::RunLoop().RunUntilIdle();

    interface_multiplexer_ =
        std::make_unique<MockObjectManagerInterfaceMultiplexer>(
            kTestInterfaceName);
    interface_multiplexer_->RegisterToObjectManager(object_manager1_.get(),
                                                    kTestServiceName1);
    interface_multiplexer_->RegisterToObjectManager(object_manager2_.get(),
                                                    kTestServiceName2);
  }

 protected:
  ForwardingObjectManagerInterface* GetForwardingInterface(
      const std::string& service_name) {
    return interface_multiplexer_->object_manager_interfaces_
        .find(service_name)
        ->second.get();
  }

  base::MessageLoop message_loop_;
  scoped_refptr<dbus::MockBus> bus_;
  scoped_refptr<dbus::MockObjectProxy> object_proxy1_;
  scoped_refptr<dbus::MockObjectProxy> object_proxy2_;
  scoped_refptr<dbus::MockObjectManager> object_manager1_;
  scoped_refptr<dbus::MockObjectManager> object_manager2_;
  std::unique_ptr<MockObjectManagerInterfaceMultiplexer> interface_multiplexer_;
};

TEST_F(ObjectManagerInterfaceMultiplexerTest, Default) {}

// Tests that CreateProperties is forwarded to a multiplexer with the correct
// additional service name parameter.
TEST_F(ObjectManagerInterfaceMultiplexerTest, CreateProperties) {
  // Service 1
  scoped_refptr<dbus::MockObjectProxy> object_proxy1 =
      new dbus::MockObjectProxy(bus_.get(), kTestServiceName1,
                                dbus::ObjectPath(kTestRootServicePath));
  auto expected_property_set1 = std::make_unique<dbus::PropertySet>(
      object_proxy1.get(), kTestInterfaceName,
      base::Bind([](const std::string& property_name) {}));
  EXPECT_CALL(*interface_multiplexer_,
              CreateProperties(kTestServiceName1, object_proxy1.get(),
                               dbus::ObjectPath(kTestRootServicePath),
                               kTestInterfaceName))
      .WillOnce(Return(expected_property_set1.get()));
  dbus::PropertySet* property_set1 =
      GetForwardingInterface(kTestServiceName1)
          ->CreateProperties(object_proxy1.get(),
                             dbus::ObjectPath(kTestRootServicePath),
                             kTestInterfaceName);
  EXPECT_EQ(expected_property_set1.get(), property_set1);

  // Service 2
  scoped_refptr<dbus::MockObjectProxy> object_proxy2 =
      new dbus::MockObjectProxy(bus_.get(), kTestServiceName2,
                                dbus::ObjectPath(kTestRootServicePath));
  auto expected_property_set2 = std::make_unique<dbus::PropertySet>(
      object_proxy2.get(), kTestInterfaceName,
      base::Bind([](const std::string& property_name) {}));
  EXPECT_CALL(*interface_multiplexer_,
              CreateProperties(kTestServiceName2, object_proxy2.get(),
                               dbus::ObjectPath(kTestRootServicePath),
                               kTestInterfaceName))
      .WillOnce(Return(expected_property_set2.get()));
  dbus::PropertySet* property_set2 =
      GetForwardingInterface(kTestServiceName2)
          ->CreateProperties(object_proxy2.get(),
                             dbus::ObjectPath(kTestRootServicePath),
                             kTestInterfaceName);
  EXPECT_EQ(expected_property_set2.get(), property_set2);
}

// Tests that ObjectAdded is forwarded to a multiplexer with the correct
// additional service name parameter.
TEST_F(ObjectManagerInterfaceMultiplexerTest, ObjectAdded) {
  // Service 1
  EXPECT_CALL(
      *interface_multiplexer_,
      ObjectAdded(kTestServiceName1, dbus::ObjectPath(kTestRootServicePath),
                  kTestInterfaceName))
      .Times(1);
  GetForwardingInterface(kTestServiceName1)
      ->ObjectAdded(dbus::ObjectPath(kTestRootServicePath), kTestInterfaceName);

  // Service 2
  EXPECT_CALL(
      *interface_multiplexer_,
      ObjectAdded(kTestServiceName2, dbus::ObjectPath(kTestRootServicePath),
                  kTestInterfaceName))
      .Times(1);
  GetForwardingInterface(kTestServiceName2)
      ->ObjectAdded(dbus::ObjectPath(kTestRootServicePath), kTestInterfaceName);
}

// Tests that ObjectRemoved is forwarded to a multiplexer with the correct
// additional service name parameter.
TEST_F(ObjectManagerInterfaceMultiplexerTest, ObjectRemoved) {
  // Service 1
  EXPECT_CALL(
      *interface_multiplexer_,
      ObjectRemoved(kTestServiceName1, dbus::ObjectPath(kTestRootServicePath),
                    kTestInterfaceName))
      .Times(1);
  GetForwardingInterface(kTestServiceName1)
      ->ObjectRemoved(dbus::ObjectPath(kTestRootServicePath),
                      kTestInterfaceName);

  // Service 2
  EXPECT_CALL(
      *interface_multiplexer_,
      ObjectRemoved(kTestServiceName2, dbus::ObjectPath(kTestRootServicePath),
                    kTestInterfaceName))
      .Times(1);
  GetForwardingInterface(kTestServiceName2)
      ->ObjectRemoved(dbus::ObjectPath(kTestRootServicePath),
                      kTestInterfaceName);
}

}  // namespace bluetooth
