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

import logging
import mm1
import modem
import pseudomodem
import state_machine
import subprocess

class ConnectMachine(state_machine.StateMachine):
    def __init__(self, modem, properties, return_cb, raise_cb):
        super(ConnectMachine, self).__init__(modem)
        self.connect_props = properties
        self.return_cb = return_cb
        self.raise_cb = raise_cb
        self.enable_initiated = False
        self.register_initiated = False

    def Cancel(self):
        logging.info('ConnectMachine: Canceling connect.')
        super(ConnectMachine, self).Cancel()
        state = self._modem.Get(mm1.I_MODEM, 'State')
        reason = mm1.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED
        if state == mm1.MM_MODEM_STATE_CONNECTING:
            logging.info('ConnectMachine: Setting state to REGISTERED.')
            self._modem.ChangeState(mm1.MM_MODEM_STATE_REGISTERED, reason)
        self._modem.connect_step = None

    def _HandleDisabledState(self):
        logging.info('ConnectMachine: Modem is DISABLED.')
        assert not self._modem.IsPendingEnable()
        if self.enable_initiated:
            message = 'ConnectMachine: Failed to enable modem.'
            logging.error(message)
            self.Cancel()
            self._modem.connect_step = None
            self.raise_cb(mm1.MMCoreError(mm1.MMCoreError.FAILED, message))
            return False
        else:
            logging.info('ConnectMachine: Initiating Enable.')
            self.enable_initiated = True
            self._modem.Enable(True)

            # state machine will spin until modem gets enabled,
            # or if enable fails
            return True

    def _HandleEnablingState(self):
        logging.info('ConnectMachine: Modem is ENABLING.')
        assert self._modem.IsPendingEnable()
        logging.info('ConnectMachine: Waiting for enable.')
        return True

    def _HandleEnabledState(self):
        logging.info('ConnectMachine: Modem is ENABLED.')

        # Check to see if a register is going on, if not,
        # start register
        if self.register_initiated:
            message = 'ConnectMachine: Failed to register.'
            logging.error(message)
            self.Cancel()
            self._modem.connect_step = None
            self.raise_cb(mm1.MMCoreError(mm1.MMCoreError.FAILED, message))
            return False
        else:
            logging.info('ConnectMachine: Waiting for Register.')
            if not self._modem.IsPendingRegister():
                try:
                    self.RegisterWithNetwork()
                except Exception as e:
                    self.raise_cb(e)
                    return False
            self.register_initiated = True
            return True

    def _HandleSearchingState(self):
        logging.info('ConnectMachine: Modem is SEARCHING.')
        logging.info('ConnectMachine: Waiting for modem to register.')
        assert self.register_initiated
        assert self._modem.IsPendingRegister()
        return True

    def _HandleRegisteredState(self):
        logging.info('ConnectMachine: Modem is REGISTERED.')
        assert not self._modem.IsPendingDisconnect()
        assert not self._modem.IsPendingEnable()
        assert not self._modem.IsPendingDisable()
        assert not self._modem.IsPendingRegister()
        logging.info('ConnectMachine: Setting state to CONNECTING.')
        reason = mm1.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED
        self._modem.ChangeState(mm1.MM_MODEM_STATE_CONNECTING, reason)
        return True

    def _GetBearerToActivate(self):
        bearer = None
        bearer_path = None
        bearer_props = {}
        for p, b in self._modem.bearers.iteritems():
            # assemble bearer props
            for key, val in self.connect_props.iteritems():
                if key in modem.ALLOWED_BEARER_PROPERTIES:
                    bearer_props[key] = val
            if (b.bearer_properties == bearer_props):
                logging.info('ConnectMachine: Found matching bearer.')
                bearer = b
                bearer_path = p
                break
        if bearer is None:
            assert bearer_path is None
            logging.info(('ConnectMachine: No matching bearer found, '
                'creating brearer with properties: ' +
                str(self.connect_props)))
            bearer_path = self._modem.CreateBearer(bearer_props)
        return bearer_path

    def _HandleConnectingState(self):
        logging.info('ConnectMachine: Modem is CONNECTING.')
        assert not self._modem.IsPendingDisconnect()
        assert not self._modem.IsPendingEnable()
        assert not self._modem.IsPendingDisable()
        assert not self._modem.IsPendingRegister()
        try:
            bearer_path = self._GetBearerToActivate()
            self._modem.ActivateBearer(bearer_path)
            logging.info('ConnectMachine: Restarting DHCP server.')
            pseudomodem.virtual_ethernet_interface.RestartDHCPServer()
            logging.info('ConnectMachine: Setting state to CONNECTED.')
            reason = mm1.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED
            self._modem.ChangeState(mm1.MM_MODEM_STATE_CONNECTED, reason)
            self._modem.connect_step = None
            logging.info(
                'ConnectMachine: Returning bearer path: %s', bearer_path)
            self.return_cb(bearer_path)
        except (mm1.MMError, subprocess.CalledProcessError) as e:
            logging.error('ConnectMachine: Failed to connect: ' + str(e))
            self.raise_cb(e)
            self._modem.ChangeState(mm1.MM_MODEM_STATE_REGISTERED,
                mm1.MM_MODEM_STATE_CHANGE_REASON_UNKNOWN)
            self._modem.connect_step = None
        return False

    def _GetModemStateFunctionMap(self):
        return {
            mm1.MM_MODEM_STATE_DISABLED: ConnectMachine._HandleDisabledState,
            mm1.MM_MODEM_STATE_ENABLING: ConnectMachine._HandleEnablingState,
            mm1.MM_MODEM_STATE_ENABLED: ConnectMachine._HandleEnabledState,
            mm1.MM_MODEM_STATE_SEARCHING: ConnectMachine._HandleSearchingState,
            mm1.MM_MODEM_STATE_REGISTERED:
                ConnectMachine._HandleRegisteredState,
            mm1.MM_MODEM_STATE_CONNECTING: ConnectMachine._HandleConnectingState
        }

    def _ShouldStartStateMachine(self):
        if self._modem.connect_step and self._modem.connect_step != self:
            # There is already a connect operation in progress.
            message = 'There is already an ongoing connect operation.'
            logging.error(message)
            self.raise_cb(mm1.MMCoreError(mm1.MMCoreError.IN_PROGRESS, message))
            return False
        elif self._modem.connect_step is None:
            # There is no connect operation going on, cancelled or otherwise.
            if self._modem.IsPendingDisable():
                message = 'Modem is currently being disabled. Ignoring ' \
                          'connect.'
                logging.error(message)
                self.raise_cb(
                    mm1.MMCoreError(mm1.MMCoreError.WRONG_STATE, message))
                return False
            state = self._modem.Get(mm1.I_MODEM, 'State')
            if state == mm1.MM_MODEM_STATE_CONNECTED:
                message = 'Modem is already connected.'
                logging.error(message)
                self.raise_cb(
                    mm1.MMCoreError(mm1.MMCoreError.CONNECTED, message))
                return False
            if state == mm1.MM_MODEM_STATE_DISCONNECTING:
                assert self._modem.IsPendingDisconnect()
                message = 'Cannot connect while disconnecting.'
                logging.error(message)
                self.raise_cb(
                    mm1.MMCoreError(mm1.MMCoreError.WRONG_STATE, message))
                return False

            logging.info('Starting Connect.')
            self._modem.connect_step = self
        return True
