# 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.

"""
Pseudomodem implementation of the org.freedesktop.ModemManager1.Modem interface.
This class serves as the abstract base class of all fake modem implementations.

"""

import bearer
import dbus
import dbus.types
import dbus_std_ifaces
import disable_machine
import enable_machine
import gobject
import logging
import mm1
import modem_simple

ALLOWED_BEARER_PROPERTIES = [
    'apn',
    'ip-type',
    'user',
    'password',
    'allow-roaming',
    'rm-protocol',
    'number'
]

class Modem(dbus_std_ifaces.DBusProperties, modem_simple.ModemSimple):
    # TODO(armansito): Implement something similar to a delegate interface
    # that can be provided by tests to fine tune the state transitions.
    # The delegate should be able to receive callbacks between state
    # transitions
    class StateMachine(object):
        def __init__(self, modem):
            self.modem = modem
            self.cancelled = False

        def Step(self):
            raise NotImplementedError()

        def Cancel(self):
            self.cancelled = True

    def __init__(self, bus=None,
                 device='pseudomodem0',
                 name='/Modem/0',
                 roaming_networks=[],
                 config=None):
        """
        Initializes the fake modem object. kwargs can contain the optional
        argument |config|, which is a dictionary of property-value mappings.
        These properties will be added to the underlying property dictionary,
        and must be one of the properties listed in the ModemManager Reference
        Manual. See _InitializeProperties for all of the properties that belong
        to this interface. Possible values for each are enumerated in mm1.py

        """

        self.device = device

        # The superclass construct will call _InitializeProperties
        dbus_std_ifaces.DBusProperties.__init__(self,
            mm1.MM1 + name, bus, config)

        self.roaming_networks = roaming_networks

        self.bearers = {}
        self.active_bearers = {}
        self.sim = None
        self.enable_step = None
        self.disable_step = None
        self.connect_step = None
        self.disconnect_step = None
        self.register_step = None

    def _InitializeProperties(self):
        """
        Sets up the default values for the properties

        """
        props = {
            'Manufacturer' : 'Banana Technologies', # be creative here
            'Model' : 'Banana Peel 3000', # yep
            'Revision' : '1.0',
            'DeviceIdentifier' : 'Banana1234567890',
            'Device' : self.device,
            'Drivers' : ['FakeDriver'],
            'Plugin' : 'Banana Plugin',
            'UnlockRequired' : dbus.types.UInt32(mm1.MM_MODEM_LOCK_NONE),
            'UnlockRetries' : {
                dbus.types.UInt32(mm1.MM_MODEM_LOCK_SIM_PIN) : (
                    dbus.types.UInt32(3))
            },
            'State' : dbus.types.Int32(mm1.MM_MODEM_STATE_DISABLED),
            'SignalQuality' : dbus.types.Struct(
                                      [dbus.types.UInt32(100), True],
                                      signature='ub'),
            'OwnNumbers' : ['5555555555'],

            # specified by subclass:
            'ModemCapabilities' :
                dbus.types.UInt32(mm1.MM_MODEM_CAPABILITY_NONE),
            'CurrentCapabilities' :
                dbus.types.UInt32(mm1.MM_MODEM_CAPABILITY_NONE),
            'MaxBearers' : dbus.types.UInt32(0),
            'MaxActiveBearers' : dbus.types.UInt32(0),
            'EquipmentIdentifier' : '',
            'AccessTechnologies' :
                    dbus.types.UInt32(mm1.MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN),
            'SupportedModes' : dbus.types.UInt32(mm1.MM_MODEM_MODE_NONE),
            'AllowedModes' : dbus.types.UInt32(mm1.MM_MODEM_MODE_NONE),
            'PreferredMode' : dbus.types.UInt32(mm1.MM_MODEM_MODE_NONE),
            'SupportedBands' : [dbus.types.UInt32(mm1.MM_MODEM_BAND_UNKNOWN)],
            'Bands' : [dbus.types.UInt32(mm1.MM_MODEM_BAND_UNKNOWN)],
            'Sim' : dbus.types.ObjectPath(mm1.ROOT_PATH)
        }
        return { mm1.I_MODEM : props }

    def IsPendingEnable(self):
        return self.enable_step and not self.enable_step.cancelled

    def IsPendingDisable(self):
        return self.disable_step and not self.disable_step.cancelled

    def IsPendingConnect(self):
        return self.connect_step and not self.connect_step.cancelled

    def IsPendingDisconnect(self):
        return self.disconnect_step and not self.disconnect_step.cancelled

    def IsPendingRegister(self):
        return self.register_step and not self.register_step.cancelled

    def SetSignalQuality(self, quality):
        self.Set(mm1.I_MODEM, 'SignalQuality', (dbus.types.Struct(
            [dbus.types.UInt32(quality), True], signature='ub')))

    def ChangeState(self, state, reason):
        old_state = self.Get(mm1.I_MODEM, 'State')
        self.SetInt32(mm1.I_MODEM, 'State', state)
        self.StateChanged(old_state, state, dbus.types.UInt32(reason))

    def SetSIM(self, sim):
        self.sim = sim
        if not sim:
            val = mm1.ROOT_PATH
        else:
            val = sim.path
            self.sim.SetBus(self.bus)
        self.Set(mm1.I_MODEM, 'Sim', dbus.types.ObjectPath(val))

    @dbus.service.method(mm1.I_MODEM, in_signature='b')
    def Enable(self, enable):
        if enable:
            logging.info('Modem enable')
            enable_machine.EnableMachine(self).Step()
        else:
            logging.info('Modem disable')
            disable_machine.DisableMachine(self).Step()

    def RegisterWithNetwork(self):
        """
        Register with the current home network, as specified
        in the constructor. Must set the state to SEARCHING first,
        and see if there is a home network available. Technology
        specific error cases need to be handled here (such as activation,
        the presence of a valid SIM card, etc)

        Must be implemented by a subclass.

        """
        raise NotImplementedError()

    def UnregisterWithNetwork(self):
        """
        Unregisters with the home network. This should transition
        the modem into the ENABLED state

        Must be implemented by a subclass

        """
        raise NotImplementedError()

    def ValidateBearerProperties(self, properties):
        """
        The default implementation makes sure that all keys in properties are
        one of the allowed bearer properties. Subclasses can override this
        method to provide CDMA/3GPP specific checks.

        Raises:
            MMCoreError, if one or more properties are invalid.
        """
        for key in properties.iterkeys():
            if key not in ALLOWED_BEARER_PROPERTIES:
                raise mm1.MMCoreError(mm1.INVALID_ARGS,
                        'Invalid property "%s", not creating bearer.' % key)

    @dbus.service.method(mm1.I_MODEM, out_signature='ao')
    def ListBearers(self):
        logging.info('ListBearers')
        return [dbus.types.ObjectPath(key) for key in self.bearers.iterkeys()]

    @dbus.service.method(mm1.I_MODEM,
                         in_signature='a{sv}',
                         out_signature='o')
    def CreateBearer(self, properties):
        logging.info('CreateBearer')
        maxbearers = self.Get(mm1.I_MODEM, 'MaxBearers')
        if len(self.bearers) == maxbearers:
            raise mm1.MMCoreError(mm1.MMCoreError.TOO_MANY,
                    ('Maximum number of bearers reached. Cannot create new '
                     'bearer.'))
        else:
            self.ValidateBearerProperties(properties)
            bearer_obj = bearer.Bearer(self.bus, properties)
            logging.info('Created bearer with path "%s".' % bearer_obj.path)
            self.bearers[bearer_obj.path] = bearer_obj
            return bearer_obj.path

    def ActivateBearer(self, bearer_path):
        logging.info('ActivateBearer: %s', bearer_path)
        bearer = self.bearers.get(bearer_path, None)
        if bearer is None:
            message = 'Could not find bearer with path "%s"' % bearer_path
            logging.info(message)
            raise mm1.MMCoreError(mm1.MMCoreError.NOT_FOUND, message)

        max_active_bearers = self.Get(mm1.I_MODEM, 'MaxActiveBearers')
        if len(self.active_bearers) >= max_active_bearers:
            message = ('Cannot activate bearer: maximum active bearer count '
                       'reached.')
            logging.info(message)
            raise mm1.MMCoreError(mm1.MMCoreError.TOO_MANY, message)
        if bearer.IsActive():
            message = 'Bearer with path "%s" already active.', bearer_path
            logging.info(message)
            raise mm1.MMCoreError(mm1.MMCoreError.CONNECTED, message)

        self.active_bearers[bearer_path] = bearer
        bearer.Connect()

    def DeactivateBearer(self, bearer_path):
        logging.info('DeactivateBearer: %s' % bearer_path)
        bearer = self.bearers.get(bearer_path, None)
        if bearer is None:
            raise mm1.MMCoreError(mm1.MMCoreError.NOT_FOUND,
                'Could not find bearer with path "%s".' % bearer_path)
        if not bearer.IsActive():
            assert bearer_path not in self.active_bearers
            raise mm1.MMCoreError(mm1.MMCoreError.WRONG_STATE,
                'Bearer with path "%s" is not active.' % bearer_path)
        assert bearer_path in self.active_bearers
        bearer.Disconnect()
        self.active_bearers.pop(bearer_path)

    @dbus.service.method(mm1.I_MODEM, in_signature='o')
    def DeleteBearer(self, bearer):
        self.Disconnect(bearer)
        if bearer in self.bearers:
            self.bearers.pop(bearer)

    @dbus.service.method(mm1.I_MODEM)
    def Reset(self):
        self.Disconnect('/')
        self.bearers.clear()
        self._properties = self._InitializeProperties()

    @dbus.service.method(mm1.I_MODEM, in_signature='s')
    def FactoryReset(self, code):
        self.Reset()

    @dbus.service.method(mm1.I_MODEM, in_signature='uu')
    def SetAllowedModes(self, modes, preferred):
        self.SetUInt32(mm1.I_MODEM, 'AllowedModes', modes)
        self.SetUInt32(mm1.I_MODEM, 'PreferredMode', preferred)

    @dbus.service.method(mm1.I_MODEM, in_signature='au')
    def SetBands(self, bands):
        band_list = [dbus.types.UInt32(band) for band in bands]
        self.Set(mm1.I_MODEM, 'Bands', band_list)

    @dbus.service.method(mm1.I_MODEM,
                         in_signature='su',
                         out_signature='s')
    def Command(self, cmd, timeout):
        return 'Bananas are tasty and fresh.'

    @dbus.service.signal(mm1.I_MODEM, signature='iiu')
    def StateChanged(self, old, new, reason):
        logging.info('Modem state changed from %u to %u for reason %u',
                old, new, reason)
