# Copyright (c) 2012 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.

"""
Python implementation of the standard interfaces:
  - org.freedesktop.DBus.Properties
  - org.freedesktop.DBus.Introspectable (TODO(armansito): May not be necessary)
  - org.freedesktop.DBus.ObjectManager

"""

import dbus
import dbus.service
import dbus.types
import logging
import mm1

class MMPropertyError(mm1.MMError):
    """
    MMPropertyError is raised by DBusProperties methods
    to indicate that a value for the given interface or
    property could not be found.

    """

    UNKNOWN_PROPERTY = 0
    UNKNOWN_INTERFACE = 1

    def __init__(self, errno, *args, **kwargs):
        super(MMPropertyError, self).__init__(errno, args, kwargs)

    def _Setup(self):
        self._error_name_base = mm1.I_MODEM_MANAGER
        self._error_name_map = {
            self.UNKNOWN_PROPERTY : '.UnknownProperty',
            self.UNKNOWN_INTERFACE : '.UnknownInterface'
        }

class DBusProperties(dbus.service.Object):
    """
    == org.freedesktop.DBus.Properties ==

    This serves as the abstract base class for all objects that expose
    properties. Each instance holds a mapping from DBus interface names to
    property-value mappings, which are provided by the subclasses.

    """

    def __init__(self, path, bus=None, config=None):
        """
        Args:
            bus -- The pydbus bus object.
            path -- The DBus object path of this object.
            config -- This is an optional dictionary that can be used to
                      initialize the property dictionary with values other
                      than the ones provided by |_InitializeProperties|. The
                      dictionary has to contain a mapping from DBus interfaces
                      to property-value pairs, and all contained keys must
                      have been initialized during |_InitializeProperties|,
                      i.e. if config contains any keys that have not been
                      already set in the internal property dictionary, an
                      error will be raised. (See DBusProperties.Set)

        """
        if not path:
            raise TypeError(('A value for "path" has to be provided that is '
                'not "None".'))
        if bus:
          dbus.service.Object.__init__(self, bus, path)
        else:
          dbus.service.Object.__init__(self, None, None)
        self.path = path
        self.bus = bus
        self._properties = self._InitializeProperties()

        if config:
            for key, props in config:
                for prop, val in props:
                    self.Set(key, prop, val)

    def SetBus(self, bus):
        self.bus = bus
        self.add_to_connection(bus, self.path)

    def SetUInt32(self, interface_name, property_name, value):
        self.Set(interface_name, property_name, dbus.types.UInt32(value))

    def SetInt32(self, interface_name, property_name, value):
        self.Set(interface_name, property_name, dbus.types.Int32(value))

    @dbus.service.method(mm1.I_PROPERTIES,
                         in_signature='ss', out_signature='v')
    def Get(self, interface_name, property_name):
        """
        Returns the value matching the given property and interface.

        Args:
            interface_name -- The DBus interface name.
            property_name -- The property name.

        Returns:
            The value matching the given property and interface.

        Raises:
            MMPropertyError, if the given interface_name or property_name
            is not exposed by this object.

        """
        logging.info(
            '%s: Get(%s, %s)',
            self.path,
            interface_name,
            property_name)
        val = self.GetAll(interface_name).get(property_name, None)
        if val is None:
            message = ("Property '%s' not implemented for interface '%s'." %
                (property_name, interface_name))
            logging.info(message)
            raise MMPropertyError(
                MMPropertyError.UNKNOWN_PROPERTY, message)
        return val

    @dbus.service.method(mm1.I_PROPERTIES, in_signature='sss')
    def Set(self, interface_name, property_name, value):
        """
        Sets the value matching the given property and interface.

        Args:
            interface_name -- The DBus interface name.
            property_name -- The property name.

        Emits:
            PropertiesChanged

        Raises:
            MMPropertyError, if the given |interface_name| or |property_name|
            is not exposed by this object.

        """
        logging.info(
            '%s: Set(%s, %s)',
            self.path,
            interface_name,
            property_name)
        props = self.GetAll(interface_name)
        if property_name not in props:
            raise MMPropertyError(
                MMPropertyError.UNKNOWN_PROPERTY,
                ("Property '%s' not implemented for "
                "interface '%s'.") %
                (property_name, interface_name))
        props[property_name] = value
        changed = { property_name : value }
        inv = self._InvalidatedPropertiesForChangedValues(changed)
        self.PropertiesChanged(interface_name, changed, inv)

    @dbus.service.method(mm1.I_PROPERTIES,
                         in_signature='s', out_signature='a{sv}')
    def GetAll(self, interface_name):
        """
        Returns all property-value pairs that match the given interface.

        Args:
            interface_name -- The DBus interface name.

        Raises:
            MMPropertyError, if the given interface_name is not exposed
            by this object.

        """
        logging.info(
            '%s: GetAll(%s)',
            self.path,
            interface_name)
        props = self._properties.get(interface_name, None)
        if props is None:
            raise MMPropertyError(
                MMPropertyError.UNKNOWN_INTERFACE,
                "Object does not implement interface '%s'." %
                interface_name)
        return props

    @dbus.service.signal(mm1.I_PROPERTIES, signature='sa{sv}as')
    def PropertiesChanged(
            self,
            interface_name,
            changed_properties,
            invalidated_properties):
        """
        This signal is emitted by Set, when the value of a property is changed.

        Args:
            interface_name -- The interface the changed properties belong to.
            changed_properties -- Dictionary containing the changed properties
                    and their new values.
            invalidated_properties -- List of properties that were invalidated
                    when properties changed.

        """
        logging.info(('Properties Changed on interface: %s Changed Properties:'
            ' %s InvalidatedProperties: %s.', interface_name,
            str(changed_properties), str(invalidated_properties)))

    def GetInterfacesAndProperties(self):
        return self._properties

    def _InvalidatedPropertiesForChangedValues(self, changed):
        """
        Called by Set, returns the list of property names that should become
        invalidated given the properties and their new values contained in
        changed. Subclasses can override this method; the default implementation
        returns an empty list.

        """
        return []

    def _InitializeProperties(self):
        """
        Called at instantiation. Subclasses have to override this method and
        return a dictionary containing mappings from implemented interfaces to
        dictionaries of property-value mappings.

        """
        raise NotImplementedError()


class DBusObjectManager(dbus.service.Object):
    """
    == org.freedesktop.DBus.ObjectManager ==

    This interface, included in rev. 0.17 of the DBus specification, allows a
    generic way to control the addition and removal of Modem objects, as well
    as the addition and removal of interfaces in the given objects.

    """

    def __init__(self, bus, path):
        dbus.service.Object.__init__(self, bus, path)
        self.devices = []
        self.bus = bus
        self.path = path

    def Add(self, device):
        """
        Adds a device to the list of devices that are managed by this modem
        manager.

        Args:
            device -- Device to add.

        Emits:
            InterfacesAdded

        """
        self.devices.append(device)
        self.InterfacesAdded(device.path, device.GetInterfacesAndProperties())

    def Remove(self, device):
        """
        Removes a device from the list of devices that are managed by this
        modem manager.

        Args:
            device -- Device to remove.

        Emits:
            InterfacesRemoved

        """
        if device in self.devices:
            self.devices.remove(device)
        interfaces = device.GetInterfacesAndProperties().keys()
        device.remove_from_connection()
        self.InterfacesRemoved(device.path, interfaces)

    @dbus.service.method(mm1.I_OBJECT_MANAGER, out_signature='a{oa{sa{sv}}}')
    def GetManagedObjects(self):
        """
        Returns:
            A dictionary containing all objects and their properties. The
            keys to the dictionary are object paths which are mapped to
            dictionaries containing mappings from DBus interface names to
            property-value pairs.

        """
        results = {}
        for device in self.devices:
            results[dbus.types.ObjectPath(device.path)] = (
                    device.GetInterfacesAndProperties())
        logging.info('%s: GetManagedObjects: %s', self.path,
                     ', '.join(results.keys()))
        return results

    @dbus.service.signal(mm1.I_OBJECT_MANAGER, signature='oa{sa{sv}}')
    def InterfacesAdded(self, object_path, interfaces_and_properties):
        logging.info((self.path + ': InterfacesAdded(' + object_path +
                     ', ' + str(interfaces_and_properties)) + ')')

    @dbus.service.signal(mm1.I_OBJECT_MANAGER, signature='oas')
    def InterfacesRemoved(self, object_path, interfaces):
        logging.info((self.path + ': InterfacesRemoved(' + object_path +
                     ', ' + str(interfaces) + ')'))
