# 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.
#
# """extract data from output of use-devices on linux box"""
# The parser takes output of "usb-devices" as rawdata, and has capablities to
# 1. Populate usb data into dictionary
# 3. Extract defined peripheral devices based on CAMERA_MAP, SPEAKER_MAP.
# 4. As of now only one type touch panel is defined here, which is Mimo.
# 5. Check usb devices's interface.
# 6. Retrieve usb device based on product and manufacturer.

import cStringIO
import textfsm

from autotest_lib.client.common_lib.cros.cfm import cfm_usb_devices

USB_DEVICES_TPLT = (
    'Value Required Vendor ([0-9a-fA-F]+)\n'
    'Value Required ProdID ([0-9A-Fa-f]+)\n'
    'Value Required prev ([0-9a-fA-Z.]+)\n'
    'Value Manufacturer (.+)\n'
    'Value Product (.+)\n'
    'Value serialnumber ([0-9a-fA-Z\:\-]+)\n'
    'Value cinterfaces (\d)\n'
    'Value List intindex ([0-9])\n'
    'Value List intdriver ([A-Za-z-\(\)]+)\n\n'
    'Start\n'
         '  ^USB-Device -> Continue.Record\n'
         '  ^P:\s+Vendor=${Vendor}\s+ProdID=${ProdID}\sRev=${prev}\n'
         '  ^S:\s+Manufacturer=${Manufacturer}\n'
         '  ^S:\s+Product=${Product}\n'
         '  ^S:\s+SerialNumber=${serialnumber}\n'
         '  ^C:\s+\#Ifs=\s+${cinterfaces}\n'
         '  ^I:\s+If\#=\s+${intindex}.*Driver=${intdriver}\n'
)



def _extract_usb_data(rawdata):
    """populate usb data into list dictionary
    @param rawdata The output of "usb-devices" on CfM.
    @returns list of dictionary, examples:
    {'Manufacturer': 'USBest Technology', 'Product': 'SiS HID Touch Controller',
     'Vendor': '266e', 'intindex': ['0'], 'tport': '00', 'tcnt': '01',
     'serialnumber': '', 'tlev': '03', 'tdev': '18', 'dver': '',
     'intdriver': ['usbhid'], 'tbus': '01', 'prev': '03.00',
     'cinterfaces': '1', 'ProdID': '0110', 'tprnt': '14'}
    """
    usbdata = []
    rawdata += '\n'
    re_table = textfsm.TextFSM(cStringIO.StringIO(USB_DEVICES_TPLT))
    fsm_results = re_table.ParseText(rawdata)
    usbdata = [dict(zip(re_table.header, row)) for row in fsm_results]
    return usbdata


def _extract_peri_device(usbdata, vid_pids):
    """retrieve the list of dictionary for certain types of VID_PID
    @param usbdata  list of dictionary for usb devices
    @param vid_pids list of vid_pid combination
    @returns the list of dictionary for certain types of VID_PID
    """
    vid_pid_usb_list = []
    for vid_pid in vid_pids:
        vid_pid_usb_list.extend(_filter_by_vid_pid(usbdata, vid_pid))
    return vid_pid_usb_list


def _get_list_audio_device(usbdata):
    """retrieve the list of dictionary for all audio devices
    @param usbdata list of dictionary for usb devices
    @returns the list of dictionary for all audio devices
    """
    audio_device_list = []
    for _data in usbdata:
        if "snd-usb-audio" in _data['intdriver']:
            audio_device_list.append(_data)
    return audio_device_list


def _get_list_video_device(usbdata):
    """retrieve the list of dictionary for all video devices
    @param usbdata list of dictionary for usb devices
    @returns the list of dictionary for all video devices
    """
    video_device_list = []
    for _data in usbdata:
        if "uvcvideo" in _data['intdriver']:
            video_device_list.append(_data)
    return video_device_list


def _get_list_mimo_device(usbdata):
    """retrieve the list of dictionary for all touch panel devices
    @param usbdata list of dictionary for usb devices
    @returns the lists of dictionary
             one for displaylink, the other for touch controller
    """
    displaylink_list = []
    touchcontroller_list = []
    for _data in usbdata:
        if "udl" in _data['intdriver']:
            displaylink_list.append(_data)
        if "SiS HID Touch Controller" == _data['Product']:
            touchcontroller_list.append(_data)
    return displaylink_list, touchcontroller_list


def _get_list_by_product(usbdata, product_name):
    """retrieve the list of dictionary based on product_name
    @param usbdata list of dictionary for usb devices
    @returns the list of dictionary
    """
    usb_list_by_product = []
    for _data in usbdata:
        if product_name == _data['Product']:
            usb_list_by_product.append(_data)
    return usb_list_by_product


def _get_list_by_manufacturer(usbdata, manufacturer_name):
    """retrieve the list of dictionary based on manufacturer_name
    @param usbdata list of dictionary for usb devices
    @returns the list of dictionary
    """
    usb_list_by_manufacturer = []
    for _data in usbdata:
        if manufacturer_name == _data['Manufacturer']:
            usb_list_by_manufacturer.append(_data)
    return usb_list_by_manufacturer


def _get_vid_and_pid(vid_pid):
  """Parses out Vendor ID and Product ID from vid:pid string.

  @param vid_pid String on format vid:pid.
  @returns (vid,pid) tuple
  """
  assert ':' in vid_pid
  return vid_pid.split(':')


def _verify_usb_device_ok(usbdata, vid_pid):
    """
    Verifies that usb device has expected usb interfaces.

    @param usbdata list of dictionary for usb devices
    @param vid_pid VID, PID combination for the USB device to check.
    """
    device_found = False
    # Retrieve a spec for this vid:pid
    usb_device = cfm_usb_devices.get_usb_device(vid_pid)
    # List of expected interfaces. This might be a sublist of the actual list of
    # interfaces. Note: we have to use lists and not sets since the list of
    # interfaces might contain duplicates.
    expected_interfaces = sorted(usb_device.interfaces)
    length = len(expected_interfaces)
    # Find all actual UsbDevices matching the vid:pid
    for _data in _filter_by_vid_pid(usbdata, vid_pid):
        device_found = True
        actual_interfaces = sorted(_data['intdriver'])[0:length]
        if not actual_interfaces == expected_interfaces:
            raise RuntimeError(
                'Device %s has unexpected interfaces.' % vid_pid)
    if not device_found:
        raise RuntimeError('Expected at least one %s connected.' % vid_pid)


def _get_speakers(usbdata):
    """get number of speaker for each type
    @param usbdata  list of dictionary for usb devices
    @returns list of dictionary, key is VID_PID, value is number of speakers
    """
    number_speaker = {}
    for speaker in cfm_usb_devices.get_speakers():
        _number = len(_filter_by_vid_pid(usbdata, speaker.vid_pid))
        number_speaker[speaker.vid_pid] = _number
    return number_speaker


def _get_cameras(usbdata):
    """get number of camera for each type
    @param usbdata  list of dictionary for usb devices
    @returns list of dictionary, key is VID_PID, value is number of cameras
    """
    number_camera = {}
    for camera in cfm_usb_devices.get_cameras():
        _number = len(_filter_by_vid_pid(usbdata, camera.vid_pid))
        number_camera[camera.vid_pid] = _number
    return number_camera


def _get_display_mimo(usbdata):
    """get number of displaylink in Mimo for each type
    @param usbdata list of dictionary for usb devices
    @returns list of dictionary, key is VID_PID, value
              is number of displaylink
    """
    number_display = {}
    for _display in cfm_usb_devices.get_mimo_displays():
        _number = len(_filter_by_vid_pid(usbdata, _display.vid_pid))
        number_display[_display.vid_pid] = _number
    return number_display


def _get_controller_mimo(usbdata):
    """get number of touch controller Mimo for each type
    @param usbdata list of dictionary for usb devices
    @returns list of dictionary, key is VID_PID, value
             is number of touch controller
    """
    number_controller = {}
    for _controller in cfm_usb_devices.get_mimo_controllers():
        _number = len(_filter_by_vid_pid(usbdata, _controller.vid_pid))
        number_controller[_controller.vid_pid] = _number
    return number_controller


def _get_preferred_speaker(peripherals):
    """
    Get string for the 1st speakers in the device list

    @param peripheral dictionary for usb devices
    @returns name of preferred speaker
    """
    for vid_pid in peripherals:
      return next((s.full_name for s in cfm_usb_devices.get_speakers()
                   if s.vid_pid == vid_pid), None)


def _get_preferred_camera(peripherals):
    """
    Get string for the 1st camera in the device list

    @param peripheral dictionary for usb devices
    @returns name of preferred camera
    """
    for vid_pid in peripherals:
      return next((c.full_name for c in cfm_usb_devices.get_cameras()
                   if c.vid_pid == vid_pid), None)


def _get_device_prod(vid_pid):
    """
    Get product for vid_pid

    @param vid_pid vid and pid combo for device
    @returns product
    """
    device = next((s for s in cfm_usb_devices.get_speakers()
                   if s.vid_pid == vid_pid), None)
    if device:
      return device
    return next((c for c in cfm_usb_devices.get_cameras()
                 if c.vid_pid == vid_pid), None)


def _filter_by_vid_pid(usbdata, vid_pid):
  """
  Utility method for filter out items by vid and pid.

  @param usbdata list of dictionaries with usb device data
  @param vid_pid list of vid_pid combination
  @return list of dictionaries with usb devices with the
     the given vid and pid
  """
  vid, pid = _get_vid_and_pid(vid_pid)
  return [u for u in usbdata if
          vid == u['Vendor'] and pid == u['ProdID']]
