# Copyright (c) 2013 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 time

from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros.cellular import mm1_constants
from autotest_lib.client.cros.cellular import test_environment
from autotest_lib.client.cros.cellular.pseudomodem import modem_3gpp
from autotest_lib.client.cros.cellular.pseudomodem import modem_cdma
from autotest_lib.client.cros.cellular.pseudomodem import pm_errors
from autotest_lib.client.cros.cellular.pseudomodem import utils as pm_utils

# Use our own connect/disconnect timeout for this test because we are using a
# a pseudomodem which should run faster than a real modem.
CONNECT_DISCONNECT_TIMEOUT = 10


def _GetModemSuperClass(family):
    """
    Obtains the correct Modem base class to use for the given family.

    @param family: The modem family. Should be one of |3GPP|/|CDMA|.
    @returns: The relevant Modem base class.
    @raises error.TestError, if |family| is not one of '3GPP' or 'CDMA'.

    """
    if family == '3GPP':
        return modem_3gpp.Modem3gpp
    elif family == 'CDMA':
        return modem_cdma.ModemCdma
    else:
        raise error.TestError('Invalid pseudomodem family: %s', family)


def GetModemDisconnectWhileStateIsDisconnecting(family):
    """
    Returns a modem that fails on disconnect request.

    @param family: The family of the modem returned.
    @returns: A modem of the given family that fails disconnect.

    """
    modem_class = _GetModemSuperClass(family)
    class _TestModem(modem_class):
        """ Actual modem implementation. """
        @pm_utils.log_dbus_method(return_cb_arg='return_cb',
                                  raise_cb_arg='raise_cb')
        def Disconnect(
            self, bearer_path, return_cb, raise_cb, *return_cb_args):
            """
            Test implementation of
            org.freedesktop.ModemManager1.Modem.Simple.Disconnect. Sets the
            modem state to DISCONNECTING and then fails, fooling shill into
            thinking that the disconnect failed while disconnecting.

            Refer to modem_simple.ModemSimple.Connect for documentation.

            """
            logging.info('Simulating failed Disconnect')
            self.ChangeState(mm1_constants.MM_MODEM_STATE_DISCONNECTING,
                             mm1_constants.MM_MODEM_STATE_CHANGE_REASON_UNKNOWN)
            time.sleep(5)
            raise pm_errors.MMCoreError(pm_errors.MMCoreError.FAILED)

    return _TestModem()


def GetModemDisconnectWhileDisconnectInProgress(family):
    """
    Returns a modem implementation that fails disconnect except the first one.

    @param family: The family of the returned modem.
    @returns: A modem of the given family that fails all but the first
            disconnect attempts.

    """
    modem_class = _GetModemSuperClass(family)
    class _TestModem(modem_class):
        """ The actual modem implementation. """
        def __init__(self):
            modem_class.__init__(self)
            self.disconnect_count = 0

        @pm_utils.log_dbus_method(return_cb_arg='return_cb',
                                  raise_cb_arg='raise_cb')
        def Disconnect(
            self, bearer_path, return_cb, raise_cb, *return_cb_args):
            """
            Test implementation of
            org.freedesktop.ModemManager1.Modem.Simple.Disconnect. Keeps
            count of successive disconnect operations and fails during all
            but the first one.

            Refer to modem_simple.ModemSimple.Connect for documentation.

            """
            # On the first call, set the state to DISCONNECTING.
            self.disconnect_count += 1
            if self.disconnect_count == 1:
                self.ChangeState(
                        mm1_constants.MM_MODEM_STATE_DISCONNECTING,
                        mm1_constants.MM_MODEM_STATE_CHANGE_REASON_UNKNOWN)
                time.sleep(5)
            else:
                raise pm_errors.MMCoreError(pm_errors.MMCoreError.FAILED)

    return _TestModem()


def GetModemDisconnectFailOther(family):
    """
    Returns a modem that fails a disconnect attempt with a generic error.

    @param family: The family of the modem returned.
    @returns: A modem of the give family that fails disconnect.

    """
    modem_class = _GetModemSuperClass(family)
    class _TestModem(modem_class):
        """ The actual modem implementation. """
        @pm_utils.log_dbus_method(return_cb_arg='return_cb',
                                  raise_cb_arg='raise_cb')
        def Disconnect(
            self, bearer_path, return_cb, raise_cb, *return_cb_args):
            """
            Test implementation of
            org.freedesktop.ModemManager1.Modem.Simple.Disconnect.
            Fails with an error.

            Refer to modem_simple.ModemSimple.Connect for documentation.

            """
            raise pm_errors.MMCoreError(pm_errors.MMCoreError.FAILED)

    return _TestModem()


class DisconnectFailTest(object):
    """
    DisconnectFailTest implements common functionality in all test cases.

    """
    def __init__(self, test, pseudomodem_family):
        self.test = test
        self._pseudomodem_family = pseudomodem_family


    def IsServiceConnected(self):
        """
        @return True, if service is connected.

        """
        service = self.test_env.shill.find_cellular_service_object()
        properties = service.GetProperties(utf8_strings=True)
        state = properties.get('State', None)
        return state in ['portal', 'online']


    def IsServiceDisconnected(self):
        """
        @return True, if service is disconnected.

        """
        service = self.test_env.shill.find_cellular_service_object()
        properties = service.GetProperties(utf8_strings=True)
        state = properties.get('State', None)
        return state == 'idle'


    def Run(self):
        """
        Runs the test.

        @raises test.TestFail, if |test_modem| hasn't been initialized.

        """
        self.test_env = test_environment.CellularPseudoMMTestEnvironment(
                pseudomm_args=(
                        {'test-module' : __file__,
                         'test-modem-class' : self._GetTestModemFunctorName(),
                         'test-modem-arg' : [self._pseudomodem_family]},))
        with self.test_env:
            self._RunTest()


    def _GetTestModemFunctorName(self):
        """ Returns the modem to be used by the pseudomodem for this test. """
        raise NotImplementedError()


    def _RunTest(self):
        raise NotImplementedError()


class DisconnectWhileStateIsDisconnectingTest(DisconnectFailTest):
    """
    Simulates a disconnect failure while the modem is still disconnecting.
    Fails if the service doesn't remain connected.

    """
    def _GetTestModemFunctorName(self):
        return 'GetModemDisconnectWhileStateIsDisconnecting'


    def _RunTest(self):
        # Connect to the service.
        service = self.test_env.shill.find_cellular_service_object()
        self.test_env.shill.connect_service_synchronous(
                service, CONNECT_DISCONNECT_TIMEOUT)

        # Disconnect attempt should fail.
        self.test_env.shill.disconnect_service_synchronous(
                service, CONNECT_DISCONNECT_TIMEOUT)

        # Service should remain connected.
        if not self.IsServiceConnected():
            raise error.TestError('Service should remain connected after '
                                  'disconnect failure.')


class DisconnectWhileDisconnectInProgressTest(DisconnectFailTest):
    """
    Simulates a disconnect failure on successive disconnects. Fails if the
    service doesn't remain connected.

    """
    def _GetTestModemFunctorName(self):
        return 'GetModemDisconnectWhileDisconnectInProgress'


    def _RunTest(self):
        # Connect to the service.
        service = self.test_env.shill.find_cellular_service_object()
        self.test_env.shill.connect_service_synchronous(
                service, CONNECT_DISCONNECT_TIMEOUT)

        # Issue first disconnect. Service should remain connected.
        self.test_env.shill.disconnect_service_synchronous(
                service, CONNECT_DISCONNECT_TIMEOUT)
        if not self.IsServiceConnected():
            raise error.TestError('Service should remain connected after '
                                  'first disconnect.')

        # Modem state should be disconnecting.
        props = self.test_env.modem.GetAll(mm1_constants.I_MODEM)
        if not props['State'] == mm1_constants.MM_MODEM_STATE_DISCONNECTING:
            raise error.TestError('Modem should be in the DISCONNECTING state.')

        # Issue second disconnect. Service should remain connected.
        self.test_env.shill.disconnect_service_synchronous(
                service, CONNECT_DISCONNECT_TIMEOUT)
        if not self.IsServiceConnected():
            raise error.TestError('Service should remain connected after '
                                  'disconnect failure.')


class DisconnectFailOtherTest(DisconnectFailTest):
    """
    Simulates a disconnect failure. Fails if the service doesn't disconnect.

    """
    def _GetTestModemFunctorName(self):
        return 'GetModemDisconnectFailOther'


    def _RunTest(self):
        # Connect to the service.
        service = self.test_env.shill.find_cellular_service_object()
        self.test_env.shill.connect_service_synchronous(
                service, CONNECT_DISCONNECT_TIMEOUT)

        # Disconnect attempt should fail.
        self.test_env.shill.disconnect_service_synchronous(
                service, CONNECT_DISCONNECT_TIMEOUT)

        # Service should be cleaned up as if disconnect succeeded.
        if not self.IsServiceDisconnected():
            raise error.TestError('Service should be disconnected.')


class cellular_DisconnectFailure(test.test):
    """
    The test uses the pseudo modem manager to simulate two failure scenarios of
    a Disconnect call: failure while the modem state is DISCONNECTING and
    failure while it is CONNECTED. The expected behavior of shill is to do
    nothing if the modem state is DISCONNECTING and to clean up the service
    otherwise.

    """
    version = 1

    def run_once(self, pseudomodem_family='3GPP'):
        tests = [
                DisconnectWhileStateIsDisconnectingTest(self,
                                                        pseudomodem_family),
                DisconnectWhileDisconnectInProgressTest(self,
                                                        pseudomodem_family),
                DisconnectFailOtherTest(self, pseudomodem_family),
        ]

        for test in tests:
            test.Run()
