# 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 dbus
import logging
import random

from autotest_lib.client.bin import test
from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros.cellular import test_environment
from autotest_lib.client.cros.cellular.pseudomodem import sim

# This is a software only test. Most time delayes are only dbus update delays.
DEFAULT_OPERATION_TIMEOUT=3

class cellular_SIMLocking(test.test):
    """
    Test the SIM locking functionality of shill.

    This test has the following test_cases:
      - Attempt to enable SIM lock with incorrect sim-pin. Verify that the
        attempt fails.
      - Successfully pin-lock the SIM.
      - Unlock a pin-locked SIM.
      - Attempt to unlock a pin-locked SIM with incorrect sim-pin, until it gets
        puk-locked.
      - Unblock a puk-locked SIM.
      - Attempt to unblock a puk-locked SIM with incorrect sim-puk, until the
        SIM gets blocked. At this point, a sim-pin2 might be expected by some
        SIMs. This test does not attempt to unlock the SIM using sim-pin2.
      - Test the functionality to change sim-pin.

    """

    version = 1

    def _bad_pin(self):
        """ Obtain a pin that does not match the valid sim-pin. """
        # Restricting the values to be  >= 1000 ensures four digit string.
        bad_pin = random.randint(1000, 9999)
        if str(bad_pin) == self.current_pin:
            bad_pin += 1
        return str(bad_pin)


    def _bad_puk(self):
        """ Obtain a puk that does not match the valid sim-puk. """
        # Restricting the values to be  >= 10000000 ensures 8 digit string.
        bad_puk = random.randint(10000000, 99999999)
        if str(bad_puk) == self.current_puk:
            bad_puk += 1
        return str(bad_puk)


    def _enter_incorrect_pin(self):
        try:
            self.device.EnterPin(self._bad_pin())
            raise error.TestFail('Cellular device did not complain although '
                                 'an incorrect pin was given')
        except dbus.DBusException as e:
            if e.get_dbus_name() == self.test_env.shill.ERROR_INCORRECT_PIN:
                logging.info('Obtained expected result: EnterPin failed with '
                             'incorrect PIN.')
            else:
                raise


    def _enter_incorrect_puk(self):
        try:
            self.device.UnblockPin(self._bad_puk(), self.current_pin)
            raise error.TestFail('Cellular device did not complain although '
                                 'an incorrect puk was given')
        except dbus.DBusException as e:
            if e.get_dbus_name() == self.test_env.shill.ERROR_INCORRECT_PIN:
                logging.info('Obtained expected result: UnblockPin failed with '
                             'incorrect PUK.')
            else:
                raise


    def _get_sim_lock_status(self):
        """ Helper method to safely obtain SIM lock status. """
        properties = self.device.GetProperties(utf8_strings=True)
        sim_lock_status = properties.get(
                self.test_env.shill.DEVICE_PROPERTY_SIM_LOCK_STATUS,
                None)
        if sim_lock_status is None:
            raise error.TestFail( 'Failed to read SIM_LOCK_STATUS.')
        return self.test_env.shill.dbus2primitive(sim_lock_status)


    def _is_sim_lock_enabled(self):
        """ Helper method to check if the SIM lock is enabled. """
        lock_status = self._get_sim_lock_status()
        lock_enabled = lock_status.get(
                self.test_env.shill.PROPERTY_KEY_SIM_LOCK_ENABLED,
                None)
        if lock_enabled is None:
            raise error.TestFail('Failed to find LockEnabled key in '
                                 'the lock status value.')
        return lock_enabled


    def _is_sim_pin_locked(self):
        """ Helper method to check if the SIM has been pin-locked. """
        lock_status = self._get_sim_lock_status()
        lock_type = lock_status.get(
                self.test_env.shill.PROPERTY_KEY_SIM_LOCK_TYPE,
                None)
        if lock_type is None:
            raise error.TestFail('Failed to find LockType key in the '
                                 'lock status value.')
        return lock_type == self.test_env.shill.VALUE_SIM_LOCK_TYPE_PIN


    def _is_sim_puk_locked(self):
        """ Helper method to check if the SIM has been puk-locked. """
        lock_status = self._get_sim_lock_status()
        lock_type = lock_status.get(
                self.test_env.shill.PROPERTY_KEY_SIM_LOCK_TYPE,
                None)
        if lock_type is None:
            raise error.TestFail('Failed to find LockType key in the '
                                 'lock status value.')
        return lock_type == self.test_env.shill.VALUE_SIM_LOCK_TYPE_PUK


    def _get_retries_left(self):
        """ Helper method to get the number of unlock retries left. """
        lock_status = self._get_sim_lock_status()
        retries_left = lock_status.get(
                self.test_env.shill.PROPERTY_KEY_SIM_LOCK_RETRIES_LEFT,
                None)
        if retries_left is None:
            raise error.TestFail('Failed to find LockRetriesLeft key '
                                 'in the lock status value.')
        if retries_left < 0:
            raise error.TestFail('Malformed RetriesLeft: %s' %
                                 str(retries_left))
        return retries_left

    def _reset_modem_with_sim_lock(self):
        """ Helper method to reset the modem with the SIM locked. """
        # When the SIM is locked, the enable operation fails and
        # hence set expect_powered flag to False.
        # The enable operation is deferred by Shill until the modem goes into
        # the disabled state after the SIM is unlocked.
        self.device, self.service = self.test_env.shill.reset_modem(
                self.device,
                expect_powered=False,
                expect_service=False)

    def _pin_lock_sim(self):
        """ Helper method to pin-lock a SIM, assuming nothing bad happens. """
        self.device.RequirePin(self.current_pin, True)
        self._reset_modem_with_sim_lock()
        if not self._is_sim_pin_locked():
            raise error.TestFail('Expected SIM to be locked after reset.')


    def _puk_lock_sim(self):
        """ Helper method to puk-lock a SIM, assuming nothing bad happens. """
        self._pin_lock_sim()
        while not self._is_sim_puk_locked():
            try:
                self._enter_incorrect_pin()
            except dbus.DBusException as e:
                if e.get_dbus_name() != self.test_env.shill.ERROR_PIN_BLOCKED:
                    raise
        if not self._is_sim_puk_locked():
            raise error.TestFail('Expected SIM to be puk-locked.')




    def test_unsuccessful_enable_lock(self):
        """ Test SIM lock enable failes with incorrect sim-pin. """
        logging.debug('Attempting to enable SIM lock with incorrect PIN.')
        try:
            self.device.RequirePin(self._bad_pin(), True)
            raise error.TestFail('Cellular device did not complain although '
                                 'an incorrect pin was given')
        except dbus.DBusException as e:
            if e.get_dbus_name() == self.test_env.shill.ERROR_INCORRECT_PIN:
                logging.info('Obtained expected result: pin-lock enable failed '
                             'with incorrect PIN.')
            else:
                raise

        if self._is_sim_lock_enabled():
            raise error.TestFail('SIM lock got enabled by incorrect PIN.')

        # SIM lock should not be enabled, and lock not set after reset.
        self.device, self.service = self.test_env.shill.reset_modem(self.device)
        self.test_env.shill.wait_for_property_in(self.service,
                                                 'state',
                                                 ['online'],
                                                 DEFAULT_OPERATION_TIMEOUT)
        if (self._is_sim_lock_enabled() or self._is_sim_pin_locked() or
            self._is_sim_puk_locked()):
            raise error.TestFail('Cellular device locked by an incorrect pin.')


    def test_cause_sim_pin_lock(self):
        """
        Test successfully enabling SIM lock and locking the SIM with
        pin-lock.

        """
        logging.debug('Attempting to enable SIM lock with correct pin.')
        self.device.RequirePin(self.current_pin, True)

        if not self._is_sim_lock_enabled():
            raise error.TestFail('SIM lock was not enabled by correct PIN.')

        self._reset_modem_with_sim_lock()
        # SIM lock should be enabled, and lock set after reset.
        if not self._is_sim_lock_enabled() or not self._is_sim_pin_locked():
            raise error.TestFail('Cellular device not locked after reset.')


    def test_unlock_sim_pin_lock(self):
        """
        Test successfully unlocking the SIM after it has been pin-locked.

        """
        # First, pin-lock the SIM.
        self._pin_lock_sim()

        retries_left = self._get_retries_left()
        self.device.EnterPin(self.current_pin)

        if self._is_sim_pin_locked():
            raise error.TestFail('Failed to unlock a pin-locked SIM with '
                                 'correct pin.')
        if not self._is_sim_lock_enabled():
            raise error.TestFail('SIM lock got disabled when attemping to'
                                 'unlock a pin-locked SIM.')
        if self._get_retries_left() != retries_left:
            raise error.TestFail('Unexpected change in number of retries left '
                                 'after a successful unlock of pin-locked SIM. '
                                 'retries before:%d, after:%d' %
                                 (retries_left, self._get_retries_left()))
        # The shill service reappears after the SIM is unlocked.
        # We need a fresh handle on the service.
        utils.poll_for_condition(
                lambda: self.test_env.shill.get_service_for_device(self.device))
        self.service = self.test_env.shill.get_service_for_device(self.device)
        self.test_env.shill.wait_for_property_in(self.service,
                                                 'state',
                                                 ['online'],
                                                 DEFAULT_OPERATION_TIMEOUT)


    def test_cause_sim_puk_lock(self):
        """ Test the flow that causes a SIM to be puk-locked. """
        # First, pin-lock the SIM.
        self._pin_lock_sim()

        # Expire all unlock pin-lock retries.
        retries_left = self._get_retries_left()
        if retries_left <= 0:
            raise error.TestFail('Expected a positive number of sim-puk '
                                 'retries.')

        while self._get_retries_left() > 1:
            # Don't execute the loop down to 0, as retries_left may be reset to
            # a higher value corresponding to the puk-lock retries.
            self._enter_incorrect_pin()
            if retries_left - self._get_retries_left() != 1:
                raise error.TestFail('RetriesLeft not decremented correctly by '
                                     'an attempt to unlock pin-lock with bad '
                                     'PIN.')
            retries_left = self._get_retries_left()

        # retries_left == 1
        try:
            self._enter_incorrect_pin()
            raise error.TestFail('Shill failed to throw PinBlocked error.')
        except dbus.DBusException as e:
            if e.get_dbus_name() != self.test_env.shill.ERROR_PIN_BLOCKED:
                raise

        # At this point, the SIM should be puk-locked.
        if not self._is_sim_lock_enabled() or not self._is_sim_puk_locked():
            raise error.TestFail('Could not puk-lock the SIM after sufficient '
                                 'incorrect attempts to unlock.')
        if not self._get_retries_left():
            raise error.TestFail('RetriesLeft not updated to puk-lock retries '
                                 'after the SIM got puk-locked.')


    def test_unlock_sim_puk_lock(self):
        """ Unlock a puk-locked SIM. """
        # First, puk-lock the SIM
        self._puk_lock_sim()

        retries_left = self._get_retries_left()
        self.device.UnblockPin(self.current_puk, self.current_pin)

        if self._is_sim_puk_locked():
            raise error.TestFail('Failed to unlock a puk-locked SIM with '
                                 'correct puk.')
        if self._is_sim_pin_locked():
            raise error.TestFail('pin-lock got unlocked while unlocking the '
                                 'puk-lock.')
        if not self._is_sim_lock_enabled():
            raise error.TestFail('SIM lock got disabled when attemping to'
                                 'unlock a pin-locked SIM.')

    def test_brick_sim(self):
        """ Test the flow that expires all pin-lock and puk-lock retries. """
        # First, puk-lock the SIM.
        self._puk_lock_sim()

        # Expire all unlock puk-lock retries.
        retries_left = self._get_retries_left()
        if retries_left <= 0:
            raise error.TestFail('Expected a positive number of sim-puk '
                                 'retries.')

        while self._get_retries_left() > 1:
            # Don't execute the loop down to 0, as the exception raised on the
            # last attempt is different.
            self._enter_incorrect_puk()
            if retries_left - self._get_retries_left() != 1:
                raise error.TestFail('RetriesLeft not decremented correctly by '
                                     'an attempt to unlock puk-lock with bad '
                                     'PUK.')
            retries_left = self._get_retries_left()

        # retries_left == 1
        try:
            self._enter_incorrect_puk()
            raise error.TestFail('Shill failed to throw SimFailure error.')
        except dbus.DBusException as e:
            if e.get_dbus_name() != self.test_env.shill.ERROR_FAILURE:
                raise


    def test_change_pin(self):
        """ Test changing pin successfully and unsuccessfully. """
        # The currently accepted behaviour of ChangePin is -- it succeeds if
        #  (1) SIM locking is enabled.
        #  (2) SIM is currently not locked.
        #  (3) The correct sim-pin is used as the old_pin argument in ChangePin.
        # ChangePin will fail in all other conditions. It sometimes fails
        # obviously, with an error. In other cases, it silently fails to change
        # the sim-pin.
        new_pin = self._bad_pin()
        # Attempt to change the sim-pin when SIM locking is not enabled.
        try:
            self.device.ChangePin(self.current_pin, new_pin)
            raise error.TestFail('Expected ChangePin to fail when SIM lock is '
                                 'not enabled.')
        except dbus.DBusException as e:
            if e.get_dbus_name() != self.test_env.shill.ERROR_FAILURE:
                raise

        self.device.RequirePin(self.current_pin, True)
        # Attempt to change the sim-pin with incorrect current sim_pin.
        try:
            self.device.ChangePin(self._bad_pin(), new_pin)
            raise error.TestFail('Expected ChangePin to fail with incorrect '
                                 'sim-pin.')
        except dbus.DBusException as e:
            if e.get_dbus_name() != self.test_env.shill.ERROR_INCORRECT_PIN:
                raise

        # Change sim-pin successfully.
        self.device.ChangePin(self.current_pin, new_pin)
        self.current_pin = new_pin
        self.device.RequirePin(self.current_pin, False)
        if self._is_sim_lock_enabled():
            raise error.TestFail('Expected to be able to disable SIM lock with '
                                 'the new sim-pin')


    def _run_internal(self, test_to_run):
        """
        Entry point to run all tests.

        @param test_to_run is a function that runs the required test.

        """
        self.current_pin = sim.SIM.DEFAULT_PIN
        self.current_puk = sim.SIM.DEFAULT_PUK

        # Resetting modemmanager invalidates the shill dbus object for the
        # modem.
        self.device = self.test_env.shill.find_cellular_device_object()
        if not self.device:
            raise error.TestFail('Failed to find a cellular device.')

        # Be a little cynical and make sure that SIM locks are as expected
        # before we begin.
        if (self._is_sim_lock_enabled() or self._is_sim_pin_locked() or
            self._is_sim_puk_locked()):
            raise error.TestFail(
                    'Cellular device in bad initial sim-lock state. '
                    'LockEnabled: %b, PinLocked:%b, PukLocked:%b.' %
                    (self._is_sim_lock_enabled(), self._is_sim_pin_locked(),
                     self._is_sim_puk_locked()))

        test_to_run()


    def run_once(self):
        """Entry function into the test."""
        random.seed()
        test_list = [self.test_unsuccessful_enable_lock,
                     self.test_cause_sim_pin_lock,
                     self.test_unlock_sim_pin_lock,
                     self.test_cause_sim_puk_lock,
                     self.test_unlock_sim_puk_lock,
                     self.test_brick_sim,
                     self.test_change_pin]

        # Some of these tests render the modem unusable, so run each test
        # with a fresh pseudomodem.
        for test in test_list:
            self.test_env = test_environment.CellularPseudoMMTestEnvironment(
                    pseudomm_args=({'family': '3GPP'},))
            with self.test_env:
                self._run_internal(test)
