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

class DisconnectMachine(state_machine.StateMachine):
    def __init__(self, modem, bearer_path, return_cb, raise_cb,
        return_cb_args=[]):
        super(DisconnectMachine, self).__init__(modem)
        self.bearer_path = bearer_path
        self.return_cb = return_cb
        self.raise_cb = raise_cb
        self.return_cb_args = return_cb_args

    def _HandleConnectedState(self):
        logging.info('DisconnectMachine: Modem state is CONNECTED.')
        logging.info('DisconnectMachine: Setting state to DISCONNECTING.')
        reason = mm1.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED
        self._modem.ChangeState(mm1.MM_MODEM_STATE_DISCONNECTING, reason)
        return True

    def _HandleDisconnectingState(self):
        logging.info('DisconnectMachine: Modem state is DISCONNECTING.')
        assert not self._modem.IsPendingConnect()
        assert not self._modem.IsPendingEnable()
        assert not self._modem.IsPendingRegister()
        assert self._modem.active_bearers
        assert self._modem.bearers

        dc_reason = mm1.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED
        try:
            if self.bearer_path == mm1.ROOT_PATH:
                for bearer in self._modem.active_bearers.keys():
                    self._modem.DeactivateBearer(bearer)
            else:
                self._modem.DeactivateBearer(self.bearer_path)
        except mm1.MMError as e:
            logging.error('DisconnectMachine: Failed to disconnect: ' + str(e))
            dc_reason = mm1.MM_MODEM_STATE_CHANGE_REASON_UNKNOWN
            self.raise_cb(e)
        finally:
            # TODO(armansito): What should happen in a disconnect
            # failure? Should we stay connected or become REGISTERED?
            logging.info('DisconnectMachine: Setting state to REGISTERED.')
            self._modem.ChangeState(mm1.MM_MODEM_STATE_REGISTERED,
                dc_reason)
            self._modem.disconnect_step = None
            logging.info('DisconnectMachine: Calling return callback.')
            self.return_cb(*self.return_cb_args)
            return False

    def _GetModemStateFunctionMap(self):
        return {
            mm1.MM_MODEM_STATE_CONNECTED:
                DisconnectMachine._HandleConnectedState,
            mm1.MM_MODEM_STATE_DISCONNECTING:
                DisconnectMachine._HandleDisconnectingState
        }

    def _ShouldStartStateMachine(self):
        if (self._modem.disconnect_step and
            # There is already a disconnect operation in progress.
            self._modem.disconnect_step != self):
            message = 'There is already an ongoing disconnect operation.'
            logging.error(message)
            self.raise_cb(
                mm1.MMCoreError(mm1.MMCoreError.IN_PROGRESS, message))
            return False
        elif self._modem.disconnect_step is None:
            # There is no disconnect operation going on, canceled or otherwise.
            state = self._modem.Get(mm1.I_MODEM, 'State')
            if state != mm1.MM_MODEM_STATE_CONNECTED:
                message = 'Modem cannot be disconnected when not connected.'
                logging.error(message)
                self.raise_cb(
                    mm1.MMCoreError(mm1.MMCoreError.WRONG_STATE, message))
                return False

            assert self._modem.bearers
            assert self._modem.active_bearers

            if self.bearer_path == mm1.ROOT_PATH:
                logging.info('All bearers will be disconnected.')
            elif not (self.bearer_path in self._modem.bearers):
                message = ('Bearer with path "%s" not found' %
                           self.bearer_path)
                logging.error(message)
                self.raise_cb(
                    mm1.MMCoreError(mm1.MMCoreError.NOT_FOUND, message))
                return False
            elif not (self.bearer_path in self._modem.active_bearers):
                message = ('No active bearer with path ' +
                    self.bearer_path +
                    ' found, current active bearers are ' +
                    str(self._modem.active_bearers))
                logging.error(message)
                self.raise_cb(mm1.MMCoreError(
                    mm1.MMCoreError.NOT_FOUND, message))
                return False

            assert not self._modem.IsPendingConnect()
            assert not self._modem.IsPendingEnable()
            assert not self._modem.IsPendingRegister()

            logging.info('Starting Disconnect.')
            self._modem.disconnect_step = self
        return True
