# 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, threading, time

from autotest_lib.server import autotest, test
from autotest_lib.client.common_lib import error

_WAIT_DELAY = 10
_LONG_TIMEOUT = 60
_WAKE_PRESS_IN_SEC=0.2

class platform_ExternalUSBStress(test.test):
    """Uses servo to repeatedly connect/remove USB devices."""
    version = 1

    def run_once(self, host, client_autotest, repeat, network_debug):
        self.has_lid = True

        # Check if DUT has lid.
        if host.servo.get('lid_open') == 'not_applicable':
            self.has_lid = False
        else:
            # Check if
            host.servo.lid_open()
            if host.servo.get('lid_open') != 'yes':
                raise error.TestError('SERVO has a bad lid_open control')

        autotest_client = autotest.Autotest(host)
        diff_list = []
        off_list = []
        # The servo hubs come up as diffs in connected components. These
        # should be ignored for this test.
        servo_hardware_prefix = 'Standard Microsystems Corp.'
        self.is_suspended = False

        def strip_lsusb_output(lsusb_output):
            """Finds the external USB devices plugged

            @param lsusb_output: lsusb command output to parse

            @returns plugged_list: List of plugged usb devices names

            """
            items = lsusb_output.split('\n')
            named_list = []
            unnamed_device_count = 0
            for item in items:
                columns = item.split(' ')
                if len(columns) == 6 or len(' '.join(columns[6:]).strip()) == 0:
                    logging.debug('Unnamed device located, adding generic name.')
                    name = 'Unnamed device %d' % unnamed_device_count
                    unnamed_device_count += 1
                else:
                    name = ' '.join(columns[6:]).strip()
                if not name.startswith(servo_hardware_prefix):
                    named_list.append(name)
            return named_list


        def set_hub_power(on=True):
            """Turns on or off the USB hub (dut_hub1_rst1).

            @param on: To power on the servo-usb hub or not

            @returns usb devices list if not suspended, None if suspended
            """
            reset = 'off'
            if not on:
                reset = 'on'
            host.servo.set('dut_hub1_rst1', reset)
            time.sleep(_WAIT_DELAY)


        def wait_to_detect(timeout=_LONG_TIMEOUT):
            """Waits till timeout for set of peripherals in lsusb output.

            @param timeout: timeout in seconds

            @raise error.TestFail: if timeout is reached

            """
            start_time = int(time.time())
            while True:
                connected = strip_lsusb_output(host.run('lsusb').stdout.strip())
                if diff_list.issubset(connected):
                    break
                elif int(time.time()) - start_time > timeout:
                    raise error.TestFail('USB peripherals not detected: %s' %
                                          str(diff_list.difference(connected)))
                time.sleep(1)


        def test_suspend(plugged_before_suspended=False,
                         plugged_before_resume=False):
            """Close and open lid while different USB plug status.

            @param plugged_before_suspended: USB plugged before suspended
            @param plugged_before_resume: USB plugged after suspended


            @raise error.TestFail: if USB peripherals do not match expectations.

            """
            set_hub_power(plugged_before_suspended)

            # Suspend
            boot_id = host.get_boot_id()
            if self.has_lid:
                host.servo.lid_close()
            else:
                thread = threading.Thread(target = host.suspend)
                thread.start()
            host.test_wait_for_sleep(_LONG_TIMEOUT)
            logging.debug(' --DUT suspended')
            self.is_suspended = True

            if plugged_before_resume is not plugged_before_suspended:
                set_hub_power(plugged_before_resume)

            # Resume
            if self.has_lid:
                host.servo.lid_open()
            else:
                host.servo.power_key(_WAKE_PRESS_IN_SEC)
            host.test_wait_for_resume(boot_id, _LONG_TIMEOUT)
            logging.debug(' --DUT resumed')
            self.is_suspended = False

            if not plugged_before_resume:
                time.sleep(_WAIT_DELAY)
                connected = strip_lsusb_output(host.run('lsusb').stdout.strip())
                if connected != off_list:
                    raise error.TestFail('Devices were not removed on wake.')
            else:
                wait_to_detect(_LONG_TIMEOUT)


        def test_hotplug():
            """Testing unplug-plug and check for expected peripherals.

             @raise error.TestFail: if USB peripherals do not match expectations.

            """
            set_hub_power(False)
            set_hub_power(True)
            wait_to_detect(_LONG_TIMEOUT)


        def stress_external_usb():
            """Test procedures in one iteration."""

            # Unplug/plug
            test_hotplug()

            # Suspend/resume as unplugged
            test_suspend()

            # Plug/close_lid/unplug/open_lid
            test_suspend(plugged_before_suspended=True)

            #Unplug/close_lid/plug/open_lid
            test_suspend(plugged_before_resume=True)

            # Suspend/resume as plugged
            test_suspend(plugged_before_suspended=True,
                         plugged_before_resume=True)


        host.servo.switch_usbkey('dut')

        # There are some mice that need the data and power connection to both
        # be removed, otherwise they won't come back up.  This means that the
        # external devices should only use the usb connections labeled:
        # USB_KEY and DUT_HUB1_USB.
        set_hub_power(False)
        time.sleep(_WAIT_DELAY)
        off_list = strip_lsusb_output(host.run('lsusb').stdout.strip())
        set_hub_power(True)
        time.sleep(_WAIT_DELAY * 2)
        connected = strip_lsusb_output(host.run('lsusb').stdout.strip())
        diff_list = set(connected).difference(set(off_list))
        if len(diff_list) == 0:
            raise error.TestError('No connected devices were detected.  Make '
                                  'sure the devices are connected to USB_KEY '
                                  'and DUT_HUB1_USB on the servo board.')
        logging.debug('Connected devices list: %s', diff_list)

        autotest_client.run_test(client_autotest,
                                 exit_without_logout=True)
        for iteration in xrange(1, repeat + 1):
            logging.debug('---Iteration %d/%d' % (iteration, repeat))
            stress_external_usb()
