# 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_LIST, SPEAKER_LIST.
# 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 manufacture.
#
import cStringIO
from autotest_lib.client.common_lib.cros import textfsm

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'
)

# As of now there are certain types of cameras, speakers and touch-panel.
# New devices can be added to these global variables.
CAMERA_LIST = ['2bd9:0011', '046d:0843', '046d:082d', '046d:0853', '064e:9405',
               '046d:085f']
CAMERA_MAP = {'2bd9:0011':'Huddly GO',
              '046d:0843':'Logitech Webcam C930e',
              '046d:082d':'HD Pro Webcam C920',
              '046d:0853':'PTZ Pro Camera',
              '046d:085f':'PTZ Pro 2',
              '064e:9405':'HD WebCam'}

SPEAKER_LIST = ['18d1:8001', '0b0e:0412', '2abf:0505']
SPEAKER_MAP = {'18d1:8001':'Hangouts Meet speakermic',
               '0b0e:0412':'Jabra SPEAK 410',
               '2abf:0505':'FLX UC 500'}

TOUCH_DISPLAY_LIST = ['17e9:016b','17e9:416d']
TOUCH_CONTROLLER_LIST = ['266e:0110']

DISPLAY_PANEL_MAP = {'17e9:016b':'DisplayLink',
                     '17e9:416d':'DisplayLink'}

TOUCH_PANEL_MAP = {'266e:0110':'SiS HID Touch Controller'}


INTERFACES_LIST = {'2bd9:0011':['uvcvideo', 'uvcvideo',
                                'uvcvideo', 'uvcvideo'],
                   '046d:0843':['uvcvideo', 'uvcvideo',
                                'snd-usb-audio', 'snd-usb-audio'],
                   '046d:082d':['uvcvideo', 'uvcvideo',
                                'snd-usb-audio', 'snd-usb-audio'],
                   '046d:085f': ['uvcvideo', 'uvcvideo','usbhid'],
                   '0b0e:0412':['snd-usb-audio', 'snd-usb-audio',
                                'snd-usb-audio'],
                   '18d1:8001':['snd-usb-audio', 'snd-usb-audio',
                                'snd-usb-audio', 'usbhid'],
                   '17e9:016b':['udl'],
                   '17e9:416d':['udl'],
                   '266e:0110':['usbhid'],
                   '046d:0853':['uvcvideo', 'uvcvideo','usbhid'],
                   '064e:9405':['uvcvideo', 'uvcvideo'],
                   '2abf:0505':['snd-usb-audio', 'snd-usb-audio',
                                'snd-usb-audio', 'usbhid']
                  }


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_pid):
    """retrive the list of dictionary for certain types of VID_PID
    @param usbdata:  list of dictionary for usb devices
    @param vid_pid: 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_pid:
        vid = _vid_pid.split(':')[0]
        pid = _vid_pid.split(':')[1]
        for _data in usbdata:
            if vid == _data['Vendor']  and pid ==  _data['ProdID']:
                vid_pid_usb_list.append(_data)
    return  vid_pid_usb_list


def get_list_audio_device(usbdata):
    """retrive 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):
    """retrive 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):
    """retrive 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):
    """retrive 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):
    """retrive 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 is_usb_device_ok(usbdata, vid_pid):
    """check usb device has expected usb interface
    @param usbdata:  list of dictionary for usb devices
    @vid_pid: VID, PID combination for each type of USB device
    @returns:
              int: number of device
              boolean: usb interfaces expected or not?
    """
    number_of_device = 0
    device_health = []
    vid = vid_pid[0:4]
    pid = vid_pid[-4:]
    for _data in usbdata:
        if vid == _data['Vendor']  and pid ==  _data['ProdID']:
            number_of_device += 1
            compare_list = _data['intdriver'][0:len(INTERFACES_LIST[vid_pid])]
            if  cmp(compare_list, INTERFACES_LIST[vid_pid]) == 0:
                device_health.append('1')
            else:
                device_health.append('0')
    return number_of_device, device_health


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 SPEAKER_LIST:
        vid =  _speaker.split(':')[0]
        pid =  _speaker.split(':')[1]
        _number = 0
        for _data in usbdata:
            if _data['Vendor'] == vid and _data['ProdID'] == pid:
                _number += 1
        number_speaker[_speaker] = _number
    return number_speaker


def get_dual_speaker(usbdata):
    """check whether dual speakers are present
    @param usbdata:  list of dictionary for usb devices
    @returns: True or False
    """
    dual_speaker = None
    speaker_dict = get_speakers(usbdata)
    for _key in speaker_dict.keys():
        if speaker_dict[_key] == 2:
            dual_speaker = _key
            break
    return dual_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 CAMERA_LIST:
        vid =  _camera.split(':')[0]
        pid =  _camera.split(':')[1]
        _number = 0
        for _data in usbdata:
            if _data['Vendor'] == vid and  _data['ProdID'] == pid:
                _number += 1
        number_camera[_camera] = _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 TOUCH_DISPLAY_LIST:
        vid =  _display.split(':')[0]
        pid =  _display.split(':')[1]
        _number = 0
        for _data in usbdata:
            if _data['Vendor'] == vid and  _data['ProdID'] == pid:
                _number += 1
        number_display[_display] = _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 TOUCH_CONTROLLER_LIST:
        vid =  _controller.split(':')[0]
        pid =  _controller.split(':')[1]
        _number = 0
        for _data in usbdata:
            if _data['Vendor'] == vid and  _data['ProdID'] == pid:
                _number += 1
        number_controller[_controller] = _number
    return number_controller

def get_preferred_speaker(peripheral):
    """get string for the 1st speakers in the device list
     @param peripheral:  of dictionary for usb devices
     @returns: string for name of preferred speake
    """
    for _key in peripheral:
        if _key in SPEAKER_LIST:
            speaker_name = SPEAKER_MAP[_key]+' ('+_key+')'
            return speaker_name

def get_preferred_camera(peripheral):
    """get string for the 1st cameras in the device list
    @param peripheral:  of dictionary for usb devices
    @returns: string for name of preferred camera
    """
    for _key in peripheral:
        if _key in CAMERA_LIST:
            camera_name = CAMERA_MAP[_key]+' ('+_key+')'
            return camera_name

def get_device_prod(vid_pid):
    """get product for vid_pid
    @param vid_pid: vid and pid combo for device
    @returns: product
    """
    for _key in SPEAKER_MAP.keys():
        if _key == vid_pid:
            return SPEAKER_MAP[_key]
    for _key in CAMERA_MAP.keys():
        if _key == vid_pid:
            return CAMERA_MAP[_key]
    for _key in DISPLAY_PANEL_MAP.keys():
        if _key == vid_pid:
            return DISPLAY_PANEL_MAP[_key]
    for _key in TOUCH_PANEL_MAP.keys():
        if _key == vid_pid:
            return TOUCH_PANEL_MAP[_key]
    return None
