#
# Copyright (C) 2016  Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions of
# the GNU General Public License v.2, or (at your option) any later version.
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY expressed or implied, including the implied warranties of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
# Public License for more details.  You should have received a copy of the
# GNU General Public License along with this program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
# source code or documentation are not subject to the GNU General Public
# License and may only be used or replicated with the express permission of
# Red Hat, Inc.
#
# Red Hat Author(s): David Lehman <dlehman@redhat.com>
#
import dbus

from .constants import BUS_NAME, OBJECT_MANAGER_INTERFACE, OBJECT_MANAGER_PATH


class ObjectManager(dbus.service.Object):
    """ Class to implement org.freedesktop.DBus.ObjectManager interface.

        Blivet's ObjectManager interface will manage subtrees for objects that
        variously (and with mutual-exclusivity) implement blivet's Device,
        Format, Action interfaces.
    """
    def __init__(self):
        self._objects = list()
        super().__init__(bus_name=dbus.service.BusName(BUS_NAME, dbus.SystemBus()),
                         object_path=OBJECT_MANAGER_PATH)

    @dbus.service.method(dbus_interface=OBJECT_MANAGER_INTERFACE, out_signature='a{oa{sa{sv}}}')
    def GetManagedObjects(self):
        return dict((obj.object_path, {obj.interface: obj.properties}) for obj in self._objects)

    def remove_object(self, obj):
        self._objects.remove(obj)
        self.InterfacesRemoved(obj.object_path, obj.interface)

    def add_object(self, obj):
        self._objects.append(obj)
        self.InterfacesAdded(obj.object_path, {obj.interface: obj.properties})

    @dbus.service.signal(dbus_interface=OBJECT_MANAGER_INTERFACE, signature='oa{sa{sv}}')
    def InterfacesAdded(self, object_path, ifaces_props_dict):
        pass

    @dbus.service.signal(dbus_interface=OBJECT_MANAGER_INTERFACE, signature='oas')
    def InterfacesRemoved(self, object_path, interfaces):
        pass

@@ -1469,16 +1469,76 @@
  list()%0A
+        self._by_id = dict()%0A        self._by_path = dict()%0A
         
@@ -1613,16 +1613,16 @@
 Bus()),%0A
-
         
@@ -1964,24 +1964,99 @@
 remove(obj)%0A
+        del self._by_id%5Bobj.id%5D%0A        del self._by_path%5Bobj.object_path%5D%0A
         self
@@ -2189,72 +2189,386 @@
 elf.
-InterfacesAdded(obj.object_path, %7Bobj.interface: obj.properties%7D
+_by_id%5Bobj.id%5D = obj%0A        self._by_path%5Bobj.object_path%5D = obj%0A        self.InterfacesAdded(obj.object_path, %7Bobj.interface: obj.properties%7D)%0A%0A    @property%0A    def objects(self):%0A        return self._objects%0A%0A    def get_object_by_id(self, obj_id):%0A        return self._by_id.get(obj_id)%0A%0A    def get_object_by_path(self, obj_path):%0A        return self._by_path.get(obj_path
 )%0A%0A 

Add mappings of objects by id and object path to ObjectManager.