#!/usr/bin/python
# Copyright 2016 The Chromium 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 re
import sys
import argparse

from devil.utils import cmd_helper
from devil.utils import lsusb

# Note: In the documentation below, "virtual port" refers to the port number
# as observed by the system (e.g. by usb-devices) and "physical port" refers
# to the physical numerical label on the physical port e.g. on a USB hub.
# The mapping between virtual and physical ports is not always the identity
# (e.g. the port labeled "1" on a USB hub does not always show up as "port 1"
# when you plug something into it) but, as far as we are aware, the mapping
# between virtual and physical ports is always the same for a given
# model of USB hub. When "port number" is referenced without specifying, it
# means the virtual port number.


# Wrapper functions for system commands to get output. These are in wrapper
# functions so that they can be more easily mocked-out for tests.
def _GetParsedLSUSBOutput():
  return lsusb.lsusb()


def _GetUSBDevicesOutput():
  return cmd_helper.GetCmdOutput(['usb-devices'])


def _GetTtyUSBInfo(tty_string):
  cmd = ['udevadm', 'info', '--name=/dev/' + tty_string, '--attribute-walk']
  return cmd_helper.GetCmdOutput(cmd)


def _GetCommList():
  return cmd_helper.GetCmdOutput('ls /dev', shell=True)


def GetTTYList():
  return [x for x in _GetCommList().splitlines() if 'ttyUSB' in x]


def GetBattorList(device_tree_map):
  return [x for x in GetTTYList() if IsBattor(x, device_tree_map)]


def IsBattor(tty_string, device_tree_map):
  (bus, device) = GetBusDeviceFromTTY(tty_string)
  node = device_tree_map[bus].FindDeviceNumber(device)
  return 'Future Technology Devices International' in node.desc


# Class to identify nodes in the USB topology. USB topology is organized as
# a tree.
class USBNode(object):
  def __init__(self):
    self._port_to_node = {}

  @property
  def desc(self):
    raise NotImplementedError

  @property
  def info(self):
    raise NotImplementedError

  @property
  def device_num(self):
    raise NotImplementedError

  @property
  def bus_num(self):
    raise NotImplementedError

  def HasPort(self, port):
    """Determines if this device has a device connected to the given port."""
    return port in self._port_to_node

  def PortToDevice(self, port):
    """Gets the device connected to the given port on this device."""
    return self._port_to_node[port]

  def Display(self, port_chain='', info=False):
    """Displays information about this node and its descendants.

    Output format is, e.g. 1:3:3:Device 42 (ID 1234:5678 Some Device)
    meaning that from the bus, if you look at the device connected
    to port 1, then the device connected to port 3 of that,
    then the device connected to port 3 of that, you get the device
    assigned device number 42, which is Some Device. Note that device
    numbers will be reassigned whenever a connected device is powercycled
    or reinserted, but port numbers stay the same as long as the device
    is reinserted back into the same physical port.

    Args:
      port_chain: [string] Chain of ports from bus to this node (e.g. '2:4:')
      info: [bool] Whether to display detailed info as well.
    """
    raise NotImplementedError

  def AddChild(self, port, device):
    """Adds child to the device tree.

    Args:
      port: [int] Port number of the device.
      device: [USBDeviceNode] Device to add.

    Raises:
      ValueError: If device already has a child at the given port.
    """
    if self.HasPort(port):
      raise ValueError('Duplicate port number')
    else:
      self._port_to_node[port] = device

  def AllNodes(self):
    """Generator that yields this node and all of its descendants.

    Yields:
      [USBNode] First this node, then each of its descendants (recursively)
    """
    yield self
    for child_node in self._port_to_node.values():
      for descendant_node in child_node.AllNodes():
        yield descendant_node

  def FindDeviceNumber(self, findnum):
    """Find device with given number in tree

    Searches the portion of the device tree rooted at this node for
    a device with the given device number.

    Args:
      findnum: [int] Device number to search for.

    Returns:
      [USBDeviceNode] Node that is found.
    """
    for node in self.AllNodes():
      if node.device_num == findnum:
        return node
    return None


class USBDeviceNode(USBNode):
  def __init__(self, bus_num=0, device_num=0, serial=None, info=None):
    """Class that represents a device in USB tree.

    Args:
      bus_num: [int] Bus number that this node is attached to.
      device_num: [int] Device number of this device (or 0, if this is a bus)
      serial: [string] Serial number.
      info: [dict] Map giving detailed device info.
    """
    super(USBDeviceNode, self).__init__()
    self._bus_num = bus_num
    self._device_num = device_num
    self._serial = serial
    self._info = {} if info is None else info

  #override
  @property
  def desc(self):
    return self._info.get('desc')

  #override
  @property
  def info(self):
    return self._info

  #override
  @property
  def device_num(self):
    return self._device_num

  #override
  @property
  def bus_num(self):
    return self._bus_num

  @property
  def serial(self):
    return self._serial

  @serial.setter
  def serial(self, serial):
    self._serial = serial

  #override
  def Display(self, port_chain='', info=False):
    print '%s Device %d (%s)' % (port_chain, self.device_num, self.desc)
    if info:
      print self.info
    for (port, device) in self._port_to_node.iteritems():
      device.Display('%s%d:' % (port_chain, port), info=info)


class USBBusNode(USBNode):
  def __init__(self, bus_num=0):
    """Class that represents a node (either a bus or device) in USB tree.

    Args:
      is_bus: [bool] If true, node is bus; if not, node is device.
      bus_num: [int] Bus number that this node is attached to.
      device_num: [int] Device number of this device (or 0, if this is a bus)
      desc: [string] Short description of device.
      serial: [string] Serial number.
      info: [dict] Map giving detailed device info.
      port_to_dev: [dict(int:USBDeviceNode)]
          Maps port # to device connected to port.
    """
    super(USBBusNode, self).__init__()
    self._bus_num = bus_num

  #override
  @property
  def desc(self):
    return 'BUS %d' % self._bus_num

  #override
  @property
  def info(self):
    return {}

  #override
  @property
  def device_num(self):
    return -1

  #override
  @property
  def bus_num(self):
    return self._bus_num

  #override
  def Display(self, port_chain='', info=False):
    print "=== %s ===" % self.desc
    for (port, device) in self._port_to_node.iteritems():
      device.Display('%s%d:' % (port_chain, port), info=info)


_T_LINE_REGEX = re.compile(r'T:  Bus=(?P<bus>\d{2}) Lev=(?P<lev>\d{2}) '
                           r'Prnt=(?P<prnt>\d{2,3}) Port=(?P<port>\d{2}) '
                           r'Cnt=(?P<cnt>\d{2}) Dev#=(?P<dev>.{3}) .*')

_S_LINE_REGEX = re.compile(r'S:  SerialNumber=(?P<serial>.*)')
_LSUSB_BUS_DEVICE_RE = re.compile(r'^Bus (\d{3}) Device (\d{3}): (.*)')


def GetBusNumberToDeviceTreeMap(fast=False):
  """Gets devices currently attached.

  Args:
    fast [bool]: whether to do it fast (only get description, not
    the whole dictionary, from lsusb)

  Returns:
    map of {bus number: bus object}
    where the bus object has all the devices attached to it in a tree.
  """
  if fast:
    info_map = {}
    for line in lsusb.raw_lsusb().splitlines():
      match = _LSUSB_BUS_DEVICE_RE.match(line)
      if match:
        info_map[(int(match.group(1)), int(match.group(2)))] = (
          {'desc':match.group(3)})
  else:
    info_map = {((int(line['bus']), int(line['device']))): line
                for line in _GetParsedLSUSBOutput()}


  tree = {}
  bus_num = -1
  for line in _GetUSBDevicesOutput().splitlines():
    match = _T_LINE_REGEX.match(line)
    if match:
      bus_num = int(match.group('bus'))
      parent_num = int(match.group('prnt'))
      # usb-devices starts counting ports from 0, so add 1
      port_num = int(match.group('port')) + 1
      device_num = int(match.group('dev'))

      # create new bus if necessary
      if bus_num not in tree:
        tree[bus_num] = USBBusNode(bus_num=bus_num)

      # create the new device
      new_device = USBDeviceNode(bus_num=bus_num,
                                 device_num=device_num,
                                 info=info_map[(bus_num, device_num)])

      # add device to bus
      if parent_num != 0:
        tree[bus_num].FindDeviceNumber(parent_num).AddChild(
            port_num, new_device)
      else:
        tree[bus_num].AddChild(port_num, new_device)

    match = _S_LINE_REGEX.match(line)
    if match:
      if bus_num == -1:
        raise ValueError('S line appears before T line in input file')
      # put the serial number in the device
      tree[bus_num].FindDeviceNumber(device_num).serial = match.group('serial')

  return tree


class HubType(object):
  def __init__(self, id_func, port_mapping):
    """Defines a type of hub.

    Args:
      id_func: [USBNode -> bool] is a function that can be run on a node
        to determine if the node represents this type of hub.
      port_mapping: [dict(int:(int|dict))] maps virtual to physical port
        numbers. For instance, {3:1, 1:2, 2:3} means that virtual port 3
        corresponds to physical port 1, virtual port 1 corresponds to physical
        port 2, and virtual port 2 corresponds to physical port 3. In the
        case of hubs with "internal" topology, this is represented by nested
        maps. For instance, {1:{1:1,2:2},2:{1:3,2:4}} means, e.g. that the
        device plugged into physical port 3 will show up as being connected
        to port 1, on a device which is connected to port 2 on the hub.
    """
    self._id_func = id_func
    # v2p = "virtual to physical" ports
    self._v2p_port = port_mapping

  def IsType(self, node):
    """Determines if the given Node is a hub of this type.

    Args:
      node: [USBNode] Node to check.
    """
    return self._id_func(node)

  def GetPhysicalPortToNodeTuples(self, node):
    """Gets devices connected to the physical ports on a hub of this type.

    Args:
      node: [USBNode] Node representing a hub of this type.

    Yields:
      A series of (int, USBNode) tuples giving a physical port
      and the USBNode connected to it.

    Raises:
      ValueError: If the given node isn't a hub of this type.
    """
    if self.IsType(node):
      for res in self._GppHelper(node, self._v2p_port):
        yield res
    else:
      raise ValueError('Node must be a hub of this type')

  def _GppHelper(self, node, mapping):
    """Helper function for GetPhysicalPortToNodeMap.

    Gets devices connected to physical ports, based on device tree
    rooted at the given node and the mapping between virtual and physical
    ports.

    Args:
      node: [USBNode] Root of tree to search for devices.
      mapping: [dict] Mapping between virtual and physical ports.

    Yields:
      A series of (int, USBNode) tuples giving a physical port
      and the Node connected to it.
    """
    for (virtual, physical) in mapping.iteritems():
      if node.HasPort(virtual):
        if isinstance(physical, dict):
          for res in self._GppHelper(node.PortToDevice(virtual), physical):
            yield res
        else:
          yield (physical, node.PortToDevice(virtual))


def GetHubsOnBus(bus, hub_types):
  """Scans for all hubs on a bus of given hub types.

  Args:
    bus: [USBNode] Bus object.
    hub_types: [iterable(HubType)] Possible types of hubs.

  Yields:
    Sequence of tuples representing (hub, type of hub)
  """
  for device in bus.AllNodes():
    for hub_type in hub_types:
      if hub_type.IsType(device):
        yield (device, hub_type)


def GetPhysicalPortToNodeMap(hub, hub_type):
  """Gets physical-port:node mapping for a given hub.
  Args:
    hub: [USBNode] Hub to get map for.
    hub_type: [HubType] Which type of hub it is.

  Returns:
    Dict of {physical port: node}
  """
  port_device = hub_type.GetPhysicalPortToNodeTuples(hub)
  return {port: device for (port, device) in port_device}


def GetPhysicalPortToBusDeviceMap(hub, hub_type):
  """Gets physical-port:(bus#, device#) mapping for a given hub.
  Args:
    hub: [USBNode] Hub to get map for.
    hub_type: [HubType] Which type of hub it is.

  Returns:
    Dict of {physical port: (bus number, device number)}
  """
  port_device = hub_type.GetPhysicalPortToNodeTuples(hub)
  return {port: (device.bus_num, device.device_num)
          for (port, device) in port_device}


def GetPhysicalPortToSerialMap(hub, hub_type):
  """Gets physical-port:serial# mapping for a given hub.
  Args:
    hub: [USBNode] Hub to get map for.
    hub_type: [HubType] Which type of hub it is.

  Returns:
    Dict of {physical port: serial number)}
  """
  port_device = hub_type.GetPhysicalPortToNodeTuples(hub)
  return {port: device.serial
          for (port, device) in port_device
          if device.serial}


def GetPhysicalPortToTTYMap(device, hub_type):
  """Gets physical-port:tty-string mapping for a given hub.
  Args:
    hub: [USBNode] Hub to get map for.
    hub_type: [HubType] Which type of hub it is.

  Returns:
    Dict of {physical port: tty-string)}
  """
  port_device = hub_type.GetPhysicalPortToNodeTuples(device)
  bus_device_to_tty = GetBusDeviceToTTYMap()
  return {port: bus_device_to_tty[(device.bus_num, device.device_num)]
          for (port, device) in port_device
          if (device.bus_num, device.device_num) in bus_device_to_tty}


def CollectHubMaps(hub_types, map_func, device_tree_map=None, fast=False):
  """Runs a function on all hubs in the system and collects their output.

  Args:
    hub_types: [HubType] List of possible hub types.
    map_func: [string] Function to run on each hub.
    device_tree: Previously constructed device tree map, if any.
    fast: Whether to construct device tree fast, if not already provided

  Yields:
    Sequence of dicts of {physical port: device} where the type of
    device depends on the ident keyword. Each dict is a separate hub.
  """
  if device_tree_map is None:
    device_tree_map = GetBusNumberToDeviceTreeMap(fast=fast)
  for bus in device_tree_map.values():
    for (hub, hub_type) in GetHubsOnBus(bus, hub_types):
      yield map_func(hub, hub_type)


def GetAllPhysicalPortToNodeMaps(hub_types, **kwargs):
  return CollectHubMaps(hub_types, GetPhysicalPortToNodeMap, **kwargs)


def GetAllPhysicalPortToBusDeviceMaps(hub_types, **kwargs):
  return CollectHubMaps(hub_types, GetPhysicalPortToBusDeviceMap, **kwargs)


def GetAllPhysicalPortToSerialMaps(hub_types, **kwargs):
  return CollectHubMaps(hub_types, GetPhysicalPortToSerialMap, **kwargs)


def GetAllPhysicalPortToTTYMaps(hub_types, **kwargs):
  return CollectHubMaps(hub_types, GetPhysicalPortToTTYMap, **kwargs)


_BUS_NUM_REGEX = re.compile(r'.*ATTRS{busnum}=="(\d*)".*')
_DEVICE_NUM_REGEX = re.compile(r'.*ATTRS{devnum}=="(\d*)".*')


def GetBusDeviceFromTTY(tty_string):
  """Gets bus and device number connected to a ttyUSB port.

  Args:
    tty_string: [String] Identifier for ttyUSB (e.g. 'ttyUSB0')

  Returns:
    Tuple (bus, device) giving device connected to that ttyUSB.

  Raises:
    ValueError: If bus and device information could not be found.
  """
  bus_num = None
  device_num = None
  # Expected output of GetCmdOutput should be something like:
  # looking at device /devices/something/.../.../...
  # KERNELS="ttyUSB0"
  # SUBSYSTEMS=...
  # DRIVERS=...
  # ATTRS{foo}=...
  # ATTRS{bar}=...
  # ...
  for line in _GetTtyUSBInfo(tty_string).splitlines():
    bus_match = _BUS_NUM_REGEX.match(line)
    device_match = _DEVICE_NUM_REGEX.match(line)
    if bus_match and bus_num == None:
      bus_num = int(bus_match.group(1))
    if device_match and device_num == None:
      device_num = int(device_match.group(1))
  if bus_num is None or device_num is None:
    raise ValueError('Info not found')
  return (bus_num, device_num)


def GetBusDeviceToTTYMap():
  """Gets all mappings from (bus, device) to ttyUSB string.

  Gets mapping from (bus, device) to ttyUSB string (e.g. 'ttyUSB0'),
  for all ttyUSB strings currently active.

  Returns:
    [dict] Dict that maps (bus, device) to ttyUSB string
  """
  result = {}
  for tty in GetTTYList():
    result[GetBusDeviceFromTTY(tty)] = tty
  return result


# This dictionary described the mapping between physical and
# virtual ports on a Plugable 7-Port Hub (model USB2-HUB7BC).
# Keys are the virtual ports, values are the physical port.
# The entry 4:{1:4, 2:3, 3:2, 4:1} indicates that virtual port
# 4 connects to another 'virtual' hub that itself has the
# virtual-to-physical port mapping {1:4, 2:3, 3:2, 4:1}.

PLUGABLE_7PORT_LAYOUT = {1:7,
                         2:6,
                         3:5,
                         4:{1:4, 2:3, 3:2, 4:1}}

def TestUSBTopologyScript():
  """Test display and hub identification."""
  # Identification criteria for Plugable 7-Port Hub
  def _is_plugable_7port_hub(node):
    """Check if a node is a Plugable 7-Port Hub
    (Model USB2-HUB7BC)
    The topology of this device is a 4-port hub,
    with another 4-port hub connected on port 4.
    """
    if not isinstance(node, USBDeviceNode):
      return False
    if '4-Port HUB' not in node.desc:
      return False
    if not node.HasPort(4):
      return False
    return '4-Port HUB' in node.PortToDevice(4).desc

  plugable_7port = HubType(_is_plugable_7port_hub,
                           PLUGABLE_7PORT_LAYOUT)
  print '==== USB TOPOLOGY SCRIPT TEST ===='

  # Display devices
  print '==== DEVICE DISPLAY ===='
  device_trees = GetBusNumberToDeviceTreeMap(fast=True)
  for device_tree in device_trees.values():
    device_tree.Display()
  print

  # Display TTY information about devices plugged into hubs.
  print '==== TTY INFORMATION ===='
  for port_map in GetAllPhysicalPortToTTYMaps([plugable_7port],
                                              device_tree_map=device_trees):
    print port_map
  print

  # Display serial number information about devices plugged into hubs.
  print '==== SERIAL NUMBER INFORMATION ===='
  for port_map in GetAllPhysicalPortToSerialMaps([plugable_7port],
                                                 device_tree_map=device_trees):
    print port_map
  print ''
  return 0

def parse_options(argv):
  """Parses and checks the command-line options.

  Returns:
    A tuple containing the options structure and a list of categories to
    be traced.
  """
  USAGE = '''./find_usb_devices [--help]
    This script shows the mapping between USB devices and port numbers.
    Clients are not intended to call this script from the command line.
    Clients are intended to call the functions in this script directly.
    For instance, GetAllPhysicalPortToSerialMaps(...)
    Running this script with --help will display this message.
    Running this script without --help will display information about
    devices attached, TTY mapping, and serial number mapping,
    for testing purposes. See design document for API documentation.
  '''
  parser = argparse.ArgumentParser(usage=USAGE)
  return parser.parse_args(argv[1:])

def main():
  parse_options(sys.argv)
  TestUSBTopologyScript()

if __name__ == "__main__":
  sys.exit(main())
