# 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 json, logging, re, time

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

_WAIT_DELAY = 5
_REQUEST_SUSPEND_CMD = ('/usr/bin/dbus-send --system / '
                        'org.chromium.PowerManager.RequestSuspend')

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

    def run_once(self, host, client_autotest, suspends, network_debug):
        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.  It is a list so when servo next
        # is available it may have a differnet hub which can be appended.
        servo_hardware_list = ['Standard Microsystems Corp.']
        client_termination_file_path = '/tmp/simple_login_exit'

        def logged_in():
            """
            Checks if the host has a logged in user.

            @return True if a user is logged in on the device.
            """
            try:
                out = host.run('cryptohome --action=status').stdout.strip()
            except:
                return False
            try:
                status = json.loads(out)
            except ValueError:
                logging.info('Cryptohome did not return a value, retrying.')
                return False

            return any((mount['mounted'] for mount in status['mounts']))


        def strip_lsusb_output(lsusb_output):
            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.info('Unnamed device located, adding generic name.')
                    name = 'Unnamed device %d' % unnamed_device_count
                    unnamed_device_count += 1
                else:
                    name = ' '.join(columns[6:]).strip()
                if name not in servo_hardware_list:
                    named_list.append(name)
            return named_list


        def set_hub_power(on=True):
            reset = 'off'
            if not on:
                reset = 'on'
            host.servo.set('dut_hub1_rst1', reset)
            time.sleep(_WAIT_DELAY)
            return strip_lsusb_output(host.run('lsusb').stdout.strip())


        def test_suspend(remove_while_suspended=False):
            set_hub_power(True)

            host.servo.lid_close()

            time.sleep(_WAIT_DELAY)
            if remove_while_suspended:
                set_hub_power(False)

            host.servo.lid_open()

            time.sleep(_WAIT_DELAY)
            connected = strip_lsusb_output(host.run('lsusb').stdout.strip())
            if remove_while_suspended:
                if connected != off_list:
                    raise error.TestFail('Devices were not removed on wake.')
                return
            if not diff_list.issubset(connected):
                raise error.TestFail('The list of connected items does not '
                                     'match the master list.\nMaster: %s\n'
                                     'Current: %s' % (diff_list, connected))


        def test_hotplug():
            # Testing hot plug so re-generate the off_list for this test
            removed = set_hub_power(False)
            connected = set_hub_power(True)
            if not diff_list.issubset(connected):
                raise error.TestFail('The list of connected items does not '
                                     'match the master list.\nMaster: %s\n'
                                     'Current: %s' % (diff_list, connected))


        def exit_client():
            host.run('touch %s' % client_termination_file_path)


        def stress_external_usb():
            if not logged_in():
                return

            # Cannot run this test, blocked on https://crosbug.com/p/16310
            # test_suspend(remove_while_suspended=True)
            test_hotplug()
            test_suspend()


        if network_debug:
            logging.info('Network debugging enabled.')
            host.run('ff_debug +dhcp')
            host.run('ff_debug --level -2')

        host.servo.switch_usbkey('dut')
        host.servo.set('usb_mux_sel3', 'dut_sees_usbkey')

        # 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.
        connected = set_hub_power(True)
        off_list = set_hub_power(False)
        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.info('Connected devices list: %s' % diff_list)
        set_hub_power(True)

        stressor = stress.CountedStressor(stress_external_usb,
                                          on_exit=exit_client)
        stressor.start(suspends, start_condition=logged_in)
        autotest_client.run_test(client_autotest)
        stressor.wait()
