# Copyright 2017 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.

"""Power cycle a usb port on DUT(device under test)."""

from __future__ import print_function

from autotest_lib.client.common_lib.cros.cfm.usb import usb_port_manager

import logging
import os
import time

TOKEN_NEW_BUS = '/:  '
TOKEN_ROOT_DEVICE = '\n    |__ '

# On board guado, there are three gpios that control usb port power:
# Front left usb port:  218, port number: 2
# Front right usb port: 219, port number: 3
# Rear dual usb ports:  209, port number: 5,6
#
# On board fizz, there are 5 usb ports and usb port power is controlled by EC
# with user space command: ectool goioset USBx_ENABLE 0/1 (x from 1 to 5).
PORT_NUM_DICT = {
    'guado': {
        # USB 2.0.
        'bus1': {
            2: 'front_left',
            3: 'front_right',
            5: 'back_dual',
            6: 'back_dual'
        },
        # USB 3.0.
        'bus2': {
            1: 'front_left',
            2: 'front_right',
            3: 'back_dual',
            4: 'back_dual'
        }
    },
    'fizz': {
        # USB 2.0.
        'bus1': {
            2: 'rear_right',
            3: 'front_right',
            4: 'front_left',
            5: 'rear_left',
            6: 'rear_middle'
        },
        # USB 3.0.
        'bus2': {
            2: 'rear_right',
            3: 'front_right',
            4: 'front_left',
            5: 'rear_left',
            6: 'rear_middle'
        }
    }
}
PORT_GPIO_DICT = {
    'guado': {
        'bus1': {
            'front_left': 218,
            'front_right': 219,
            'back_dual': 209
        },
        'bus2': {
            'front_left': 218,
            'front_right': 219,
            'back_dual': 209
        }
    },
    'fizz': {
        'bus1': {
            'rear_left': 1,
            'rear_middle': 2,
            'rear_right': 3,
            'front_right': 4,
            'front_left': 5
        },
        'bus2': {
            'rear_left': 1,
            'rear_middle': 2,
            'rear_right': 3,
            'front_right': 4,
            'front_left': 5
        }
    }
}


def power_cycle_usb_vidpid(dut, board, vid, pid, pause=1):
    """
    Power cycle a usb port on DUT via peripharel's VID and PID.

    When only the VID and PID of the peripharel is known, a search is needed
    to decide which port it connects to by its VID and PID and look up the gpio
    index according to the board and port number in the dictionary. Then the
    USB port is power cycled using the gpio number.

    @param dut: The handle of the device under test.
    @param board: Board name ('guado', etc.)
    @param vid: Vendor ID of the peripharel device.
    @param pid: Product ID of the peripharel device.
    @param pause: Time interval between power off and power on, unit is second.

    @raise KeyError if the target device wasn't found by given VID and PID.

    """
    bus_idx, port_idx = get_port_number_from_vidpid(dut, vid, pid)
    if port_idx is None:
        raise KeyError('Couldn\'t find target device, {}:{}.'.format(vid, pid))
    logging.info('found device bus {} port {}'.format(bus_idx, port_idx))

    usb_manager = usb_port_manager.UsbPortManager(dut)
    port_id = [usb_port_manager.PortId(bus=bus_idx, port_number=port_idx)]
    usb_manager.set_port_power(port_id, 0)
    time.sleep(pause)
    usb_manager.set_port_power(port_id, 1)


def get_port_number_from_vidpid(dut, vid, pid):
    """
    Get bus number and port number a device is connected to on DUT.

    Get the bus number and port number of the usb port the target perpipharel
    device is connected to.

    @param dut: The handle of the device under test.
    @param vid: Vendor ID of the peripharel device.
    @param pid: Product ID of the peripharel device.

    @returns the target bus number and port number, if device not found, returns
          (None, None).

    """
    cmd = 'lsusb -d {}:{}'.format(vid, pid)
    lsusb_output = dut.run(cmd, ignore_status=True).stdout
    logging.info('lsusb output {}'.format(lsusb_output))
    target_bus_idx, target_dev_idx = get_bus_dev_id(lsusb_output, vid, pid)
    if target_bus_idx is None:
        return None, None
    cmd = 'lsusb -t'
    lsusb_output = dut.run(cmd, ignore_status=True).stdout
    target_port_number = get_port_number(
        lsusb_output, target_bus_idx, target_dev_idx)
    return target_bus_idx, target_port_number


def get_bus_dev_id(lsusb_output, vid, pid):
    """
    Get bus number and device index a device is connected to on DUT.

    Get the bus number and port number of the usb port the target perpipharel
    device is connected to based on the output of command 'lsusb -d VID:PID'.

    @param lsusb_output: output of command 'lsusb -d VID:PID' running on DUT.
    @param vid: Vendor ID of the peripharel device.
    @param pid: Product ID of the peripharel device.

    @returns the target bus number and device index, if device not found,
          returns (None, None).

    """
    if lsusb_output == '':
        return None, None
    lsusb_device_info = lsusb_output.strip().split('\n')
    if len(lsusb_device_info) > 1:
        logging.info('find more than one device with VID:PID: %s:%s', vid, pid)
        return None, None
    # An example of the info line is 'Bus 001 Device 006:  ID 266e:0110 ...'
    fields = lsusb_device_info[0].split(' ')
    assert len(fields) >= 6, 'Wrong info format: {}'.format(lsusb_device_info)
    target_bus_idx = int(fields[1])
    target_device_idx = int(fields[3][:-1])
    logging.info('found target device %s:%s, bus: %d, dev: %d',
                 vid, pid, target_bus_idx, target_device_idx)
    return target_bus_idx, target_device_idx

def get_port_number(lsusb_tree_output, bus, dev):
    """
    Get port number that certain device is connected to on DUT.

    Get the port number of the usb port that the target peripharel device is
    connected to based on the output of command 'lsusb -t', its bus number and
    device index.
    An example of lsusb_tree_output could be:
    /:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
        |__ Port 2: Dev 2, If 0, Class=Hub, Driver=hub/4p, 5000M
    /:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/11p, 480M
        |__ Port 2: Dev 52, If 0, Class=Hub, Driver=hub/4p, 480M
            |__ Port 1: Dev 55, If 0, Class=Human Interface Device,
                        Driver=usbhid, 12M
            |__ Port 3: Dev 54, If 0, Class=Vendor Specific Class,
                        Driver=udl, 480M
        |__ Port 3: Dev 3, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 4: Dev 4, If 0, Class=Wireless, Driver=btusb, 12M
        |__ Port 4: Dev 4, If 1, Class=Wireless, Driver=btusb, 12M

    @param lsusb_tree_output: The output of command 'lsusb -t' on DUT.
    @param bus: The bus number the peripharel device is connected to.
    @param dev: The device index of the peripharel device on DUT.

    @returns the target port number, if device not found, returns None.

    """
    lsusb_device_buses = lsusb_tree_output.strip().split(TOKEN_NEW_BUS)
    target_bus_token = 'Bus {:02d}.'.format(bus)
    for bus_info in lsusb_device_buses:
        if bus_info.find(target_bus_token) != 0:
            continue
        target_dev_token = 'Dev {}'.format(dev)
        device_info = bus_info.strip(target_bus_token).split(TOKEN_ROOT_DEVICE)
        for device in device_info:
            if target_dev_token not in device:
                continue
            target_port_number = int(device.split(':')[0].split(' ')[1])
            return target_port_number
    return None


def get_all_port_number_from_vidpid(dut, vid, pid):
    """
    Get the list of bus number and port number devices are connected to DUT.

    Get the the list of bus number and port number of the usb ports the target
           perpipharel devices are connected to.

    @param dut: The handle of the device under test.
    @param vid: Vendor ID of the peripharel device.
    @param pid: Product ID of the peripharel device.

    @returns the list of target bus number and port number, if device not found,
            returns empty list.

    """
    port_number = []
    cmd = 'lsusb -d {}:{}'.format(vid, pid)
    lsusb_output = dut.run(cmd, ignore_status=True).stdout
    (target_bus_idx, target_dev_idx) = get_all_bus_dev_id(lsusb_output, vid, pid)
    if target_bus_idx is None:
        return None, None
    cmd = 'lsusb -t'
    lsusb_output = dut.run(cmd, ignore_status=True).stdout
    for bus, dev in zip(target_bus_idx, target_dev_idx):
        port_number.append(get_port_number(
            lsusb_output, bus, dev))
    return (target_bus_idx, port_number)


def get_all_bus_dev_id(lsusb_output, vid, pid):
    """
    Get the list of bus number and device index devices are connected to DUT.

    Get the bus number and port number of the usb ports the target perpipharel
            devices are connected to based on the output of command 'lsusb -d VID:PID'.

    @param lsusb_output: output of command 'lsusb -d VID:PID' running on DUT.
    @param vid: Vendor ID of the peripharel device.
    @param pid: Product ID of the peripharel device.

    @returns the list of target bus number and device index, if device not found,
           returns empty list.

    """
    bus_idx = []
    device_idx =[]
    if lsusb_output == '':
        return None, None
    lsusb_device_info = lsusb_output.strip().split('\n')
    for lsusb_device in lsusb_device_info:
        fields = lsusb_device.split(' ')
        assert len(fields) >= 6, 'Wrong info format: {}'.format(lsusb_device_info)
        target_bus_idx = int(fields[1])
        target_device_idx = int(fields[3][:-1])
        bus_idx.append(target_bus_idx)
        device_idx.append( target_device_idx)
    return (bus_idx, device_idx)


def get_target_all_gpio(dut, board, vid, pid):
    """
    Get GPIO for all devices with vid, pid connected to on DUT.

    Get gpio of usb port the target perpipharel  devices are
    connected to based on the output of command 'lsusb -d VID:PID'.

    @param dut: The handle of the device under test.
    @param board: Board name ('guado', etc.)
    @param vid: Vendor ID of the peripharel device.
    @param pid: Product ID of the peripharel device.

    @returns the list of gpio, if no device found return []

    """
    gpio_list = []
    (bus_idx, port_idx) = get_all_port_number_from_vidpid(dut, vid, pid)
    if port_idx is None:
        raise KeyError('Couldn\'t find target device, {}:{}.'.format(vid, pid))

    for bus, port in zip(bus_idx, port_idx):
        logging.info('found device bus {} port {}'.format(bus, port))
        token_bus = 'bus{}'.format(bus)
        target_gpio_pos = (PORT_NUM_DICT.get(board, {})
                       .get(token_bus, {}).get(port, ''))
        target_gpio = (PORT_GPIO_DICT.get(board, {})
                   .get(token_bus, {}).get(target_gpio_pos, None))
        logging.info('Target gpio num {}'.format(target_gpio))
        gpio_list.append(target_gpio)
    return gpio_list
