#!/usr/bin/env python2
# 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.
"""Python version of Servo hardware debug & control board server."""

import errno
import logging
import optparse
import os
import pkg_resources
import select
import SimpleXMLRPCServer
import socket
import sys
import usb

import drv.loglevel
import ftdi_common
import multiservo
import servo_interfaces
import servo_server
import system_config
import terminal_freezer

VERSION = pkg_resources.require('servo')[0].version

MAX_ISERIAL_STR = 128

# If user does not specify a port to use, try ports in this range. Traverse
# the range from high to low addresses to maintain backwards compatibility
# (the first checked default port is 9999, the range is such that all possible
# port numbers are 4 digits).
DEFAULT_PORT_RANGE = (9990, 9999)

# This text file holds servod configuration parameters. This is especially
# handy for multi servo operation.
#
# The file format is pretty loose:
#  - text starting with # is ignored til the end of the line
#  - empty lines are ignored
#  - configuration lines consist of up to 4 comma separated fields (all
#    but the first field optional):
#        servo-name, serial-number, port-number, board-name
#
#    where
#     . servo-name - a user defined symbolic name, just a reference
#                     to a certain servo board
#     . serial-number - serial number of the servo board this line pertains to
#     . port-number - desired port number for servod for this board, can be
#                     overridden by the command line switch --port or
#                     environment variable setting SERVOD_PORT
#     . board-name - board configuration file to use, can be
#                     overridden by the command line switch --board
#
# Since the same parameters could be defined using different means, there is a
# hierarchy of definitions:
#   command line <- environment definition <- rc config file
DEFAULT_RC_FILE = '/home/%s/.servodrc' % os.getenv('SUDO_USER', '')


class ServodError(Exception):
  """Exception class for servod server."""


# TODO(tbroch) merge w/ parse_common_args properly
def _parse_args():
  """Parse commandline arguments.

  Note, reads sys.argv directly

  Returns:
    tuple (options, args) from optparse.parse_args().
  """
  description = (
      '%prog is server to interact with servo debug & control board.  '
      'This server communicates to the board via USB and the client via '
      'xmlrpc library.  Launcher most specify at least one --config <file> '
      'in order for the server to provide any functionality.  In most cases, '
      'multiple configs will be needed to expose complete functionality '
      'between debug & DUT board.')
  examples = (
      '\nExamples:\n   > %prog -b <path>/data/servo.xml\n\tLaunch server on '
      'defualt host:port with configs native to servo\n   > %prog -b <file> -p '
      '8888\n\tLaunch server listening on port 8888\n   > %prog -b <file> -v '
      '0x18d1 -p 0x5001\n\tLaunch targetting usb device \n\twith vid:pid == '
      '0x18d1:0x5001 (Google/Servo)\n')
  parser = optparse.OptionParser(version='%prog ' + VERSION)
  parser.description = description
  parser.add_option('-d', '--debug', action='store_true', default=False,
                    help='enable debug messages')
  parser.add_option('', '--host', default='localhost', type=str,
                    help='hostname to start server on')
  parser.add_option(
      '', '--port', default=None, type=int,
      help='port for server to listen on, by default '
      'will try ports in %d..%d range, could also be '
      'supplied through environment variable SERVOD_PORT' % DEFAULT_PORT_RANGE)
  parser.add_option('-v', '--vendor', default=None, type=int,
                    help='vendor id of ftdi device to interface to')
  parser.add_option('-p', '--product', default=None, type=int,
                    help='USB product id of ftdi device to interface with')
  parser.add_option('-s', '--serialname', default=None, type=str,
                    help='device serialname stored in eeprom')
  parser.add_option('-c', '--config', default=None, type=str, action='append',
                    help='system config files (XML) to read')
  parser.add_option('-b', '--board', default='', type=str, action='store',
                    help='include config file (XML) for given board')
  parser.add_option('--noautoconfig', action='store_true', default=False,
                    help='Disable automatic determination of config files')
  parser.add_option('-i', '--interfaces', type=str, default='',
                    help='ordered space-delimited list of interfaces.  ' +
                    'Valid choices are gpio|i2c|uart|gpiouart|dummy')
  parser.add_option('-u', '--usbkm232', type=str,
                    help='path to USB-KM232 device which allow for '
                    'sending keyboard commands to DUTs that do not '
                    'have built in keyboards. Used in FAFT tests. '
                    '(Optional), e.g. /dev/ttyUSB0')

  multiservo.add_multiservo_parser_options(parser)
  parser.set_usage(parser.get_usage() + examples)
  return parser.parse_args()


def usb_get_iserial(device):
  """Get USB device's iSerial string

  Args:
    device: usb.Device object

  Returns:
    iserial: USB devices iSerial string or empty string if the device has
             no serial number.
  """
  device_handle = device.open()
  # The device has no serial number string descriptor.
  if device.iSerialNumber == 0:
    return ''
  iserial = ''
  try:
    iserial = device_handle.getString(device.iSerialNumber, MAX_ISERIAL_STR)
  except usb.USBError, e:
    # TODO(tbroch) other non-FTDI devices on my host cause following msg
    #   usb.USBError: error sending control message: Broken pipe
    # Need to investigate further
    pass
  return iserial


def usb_find(vendor, product, serialname):
  """Find USB devices based on vendor, product and serial identifiers.

  Locates all USB devices that match the criteria of the arguments.  In the
  case where input arguments are 'None' that argument is a don't care

  Args:
    vendor: USB vendor id (integer)
    product: USB product id (integer)
    serial: USB serial id (string)

  Returns:
    matched_devices : list of pyusb devices matching input args
  """
  matched_devices = []
  for bus in usb.busses():
    for device in bus.devices:
      if (not vendor or device.idVendor == vendor) and \
            (not product or device.idProduct == product) and \
            (not serialname or usb_get_iserial(device).endswith(serialname)):
        matched_devices.append(device)
  return matched_devices


def find_servod_match(logger, options, all_servos, servodrc):
  """Find a servo matching one of servodrc lines

  Given a list of servod objects matching discovered servos, display the list
  to the user and check if there is a configuration file line corresponding to
  one of the servos.

  If a line like that exists, and it includes options which are not yet
  defined in the options object - set these options' values. If the option is
  already defined - report that this config line setting is ignored.

  Args:
    logger: a logging instance used by this servod driver
    options: an options object as returned by parse_options
    all_servos: a list of servod objects corresponding to discovered servo
                devices
    servodrc: a dictionary representing the contents of the servodrc file, as
              returned by parse_rc() above (if any)

  Returns:
    a matching servod object, if found, None otherwise

  Raises:
    ServodEror in case required name is not found in the config file
  """

  for servo in all_servos:
    logger.info('Found servo, vid: 0x%04x pid: 0x%04x sid: %s', servo.idVendor,
                servo.idProduct, usb_get_iserial(servo))

  # If user specified servod name in the command line - match it to the serial
  # number.

  if options.name:
    config = servodrc.get(options.name)
    if not config:
      raise ServodError("Name '%s' not in the config file" % options.name)
    options.serialname = config['sn']
  elif options.serialname:
    # Let's try finding config for a serial name
    for config in servodrc.itervalues():
      if config['sn'] == options.serialname:
        break
    else:
      return None

  if not options.serialname:
    # There is nothing to match
    return None

  for servo in all_servos:
    servo_sn = usb_get_iserial(servo)
    if servo_sn != options.serialname:
      continue

    # Match found, some sanity checks/updates before using it
    matching_servo = servo
    rc_port = config['port']
    if rc_port:
      if not options.port:
        options.port = rc_port
      elif options.port != rc_port:
        logger.warning('Ignoring rc configured port %s for servo %s', rc_port,
                       servo_sn)

    rc_board = config['board']
    if rc_board:
      if not options.board:
        options.board = rc_board
      elif options.board != rc_board:
        logger.warning('Ignoring rc configured board name %s for servo %s',
                       rc_board, servo_sn)
    return matching_servo

  raise ServodError('No matching servo found')


def choose_servo(logger, all_servos):
  """Let user choose a servo from available list of unique devices.

  Args:
    logger: a logging instance used by this servod driver
    all_servos: a list of servod objects corresponding to discovered servo
                devices

  Returns:
    servo object for the matching (or single) device, otherwise None
  """
  logger.info('')
  for i, servo in enumerate(all_servos):
    logger.info("Press '%d' for servo, vid: 0x%04x pid: 0x%04x sid: %s", i,
                servo.idVendor, servo.idProduct, usb_get_iserial(servo))

  (rlist, _, _) = select.select([sys.stdin], [], [], 10)
  if not rlist:
    logger.warn('Timed out waiting for your choice\n')
    return None

  rsp = rlist[0].readline().strip()
  try:
    rsp = int(rsp)
  except ValueError:
    logger.warn('%s not a valid choice ... ignoring', rsp)
    return None

  if rsp < 0 or rsp >= len(all_servos):
    logger.warn('%s outside of choice range ... ignoring', rsp)
    return None

  logging.info('')
  servo = all_servos[rsp]
  logging.info('Chose %d ... starting servod on servo '
               'vid: 0x%04x pid: 0x%04x sid: %s', rsp, servo.idVendor,
               servo.idProduct, usb_get_iserial(servo))
  logging.info('')
  return servo


def discover_servo(logger, options, servodrc):
  """Find a servo USB device to use

  First, find all servo devices matching command line options, this may result
  in discovering none, one or more devices.

  Then try matching discovered servos and the configuration defined in
  servodrc. A match this will result in reading missing options from servodrc
  file.

  If there is a match - return the matching device.

  If no match found, but there is only one servo connected - return it. If
  there is no match found and multiple servos are connected - report an error
  and return None.

  Args:
    logger: a logging instance used by this servod driver
    options: the options object returned by opt_parse
    servodrc: a dictionary representing the contents of the servodrc file, as
              returned by parse_rc() above (if any)
  Returns:
    servo object for the matching (or single) device, otherwise None
  """

  vendor, product, serialname = (options.vendor, options.product,
                                 options.serialname)
  all_servos = []
  for (vid, pid) in servo_interfaces.SERVO_ID_DEFAULTS:
    if (vendor and vendor != vid) or \
          (product and product != pid):
      continue
    all_servos.extend(usb_find(vid, pid, serialname))

  if not all_servos:
    logger.error('No servos found')
    return None

  # See if there is a matching entry in servodrc
  matching_servo = find_servod_match(logger, options, all_servos, servodrc)

  if matching_servo:
    return matching_servo

  if len(all_servos) == 1:
    return all_servos[0]

  # See if only one primary servo. Filter secordary servos, like servo-micro.
  SECONDARY_SERVOS = (
      servo_interfaces.SERVO_MICRO_DEFAULTS + servo_interfaces.CCD_DEFAULTS)
  all_primary_servos = [
      servo for servo in all_servos
      if (servo.idVendor, servo.idProduct) not in SECONDARY_SERVOS
  ]
  if len(all_primary_servos) == 1:
    return all_primary_servos[0]

  # Let user choose a servo
  matching_servo = choose_servo(logger, all_servos)
  if matching_servo:
    return matching_servo

  logger.error('Use --vendor, --product or --serialname switches to '
               'identify servo uniquely, or create a servodrc file '
               ' and use the --name switch')

  return None


def get_board_version(lot_id, product_id):
  """Get board version string.

  Typically this will be a string of format <boardname>_<version>.
  For example, servo_v2.

  Args:
    lot_id: string, identifying which lot device was fabbed from or None
    product_id: integer, USB product id

  Returns:
    board_version: string, board & version or None if not found
  """
  if lot_id:
    for (board_version, lot_ids) in \
          ftdi_common.SERVO_LOT_ID_DEFAULTS.iteritems():
      if lot_id in lot_ids:
        return board_version

  for (board_version, vids) in \
        ftdi_common.SERVO_PID_DEFAULTS.iteritems():
    if product_id in vids:
      return board_version

  return None


def get_lot_id(logger, servo):
  """Get lot_id for a given servo.

  Args:
    servo: usb.Device object

  Returns:
    lot_id of the servo device.
  """
  lot_id = None
  iserial = usb_get_iserial(servo)
  logger.debug('iserial = %s', iserial)
  if not iserial:
    logger.warn('Servo device has no iserial value')
  else:
    try:
      (lot_id, _) = iserial.split('-')
    except ValueError:
      logger.warn("Servo device's iserial was unrecognized.")
  return lot_id


def get_auto_configs(logger, board_version):
  """Get xml configs that should be loaded.

  Args:
    board_version: string, board & version

  Returns:
    configs: list of XML config files that should be loaded
  """
  if board_version not in ftdi_common.SERVO_CONFIG_DEFAULTS:
    logger.warning('Unable to determine configs to load for board version = %s',
                   board_version)
    return []
  return ftdi_common.SERVO_CONFIG_DEFAULTS[board_version]


def main_function():
  (options, args) = _parse_args()
  if options.debug:
    level = 'debug'
  else:
    level = drv.loglevel.DEFAULT_LOGLEVEL

  loglevel, format = drv.loglevel.LOGLEVEL_MAP[level]
  logging.basicConfig(level=loglevel, format=format)

  # Servod needs to be running in the chroot without PID namespaces in order to
  # freeze terminals when reading from the UARTs.
  terminal_freezer.CheckForPIDNamespace()

  logger = logging.getLogger(os.path.basename(sys.argv[0]))
  logger.info('Start')
  multiservo.get_env_options(logger, options)

  if options.name and options.serialname:
    logger.error("Mutually exclusive '--name' or '--serialname' is allowed")
    sys.exit(-1)

  servo_device = discover_servo(logger, options,
                                multiservo.parse_rc(logger, options.rcfile))
  if not servo_device:
    sys.exit(-1)

  lot_id = get_lot_id(logger, servo_device)
  board_version = get_board_version(lot_id, servo_device.idProduct)
  logger.debug('board_version = %s', board_version)
  all_configs = []
  if not options.noautoconfig:
    all_configs += get_auto_configs(logger, board_version)

  if options.config:
    for config in options.config:
      # quietly ignore duplicate configs for backwards compatibility
      if config not in all_configs:
        all_configs.append(config)

  if not all_configs:
    raise ServodError('No automatic config found,'
                      ' and no config specified with -c <file>')

  scfg = system_config.SystemConfig()

  if options.board:
    board_config = 'servo_' + options.board + '_overlay.xml'
    if not scfg.find_cfg_file(board_config):
      logger.error('No XML overlay for board %s', options.board)
      sys.exit(-1)

    logger.info('Found XML overlay for board %s', options.board)
    all_configs.append(board_config)

  for cfg_file in all_configs:
    scfg.add_cfg_file(cfg_file)

  logger.debug('\n' + scfg.display_config())

  logger.debug('Servo is vid:0x%04x pid:0x%04x sid:%s' % \
                 (servo_device.idVendor, servo_device.idProduct,
                  usb_get_iserial(servo_device)))

  if options.port:
    start_port = options.port
    end_port = options.port
  else:
    end_port, start_port = DEFAULT_PORT_RANGE
  for servo_port in xrange(start_port, end_port - 1, -1):
    try:
      server = SimpleXMLRPCServer.SimpleXMLRPCServer((options.host, servo_port),
                                                     logRequests=False)
      break
    except socket.error as e:
      if e.errno == errno.EADDRINUSE:
        continue  # Port taken, see if there is another one next to it.
      logger.fatal("Problem opening Server's socket: %s", e)
      sys.exit(-1)
  else:
    if options.port:
      err_msg = ('Port %d is busy' % options.port)
    else:
      err_msg = ('Could not find a free port in %d..%d range' % (end_port,
                                                                 start_port))

    logger.fatal(err_msg)
    sys.exit(-1)

  servod = servo_server.Servod(
      scfg, vendor=servo_device.idVendor, product=servo_device.idProduct,
      serialname=usb_get_iserial(servo_device),
      interfaces=options.interfaces.split(), board=options.board,
      version=board_version, usbkm232=options.usbkm232)
  servod.hwinit(verbose=True)
  server.register_introspection_functions()
  server.register_multicall_functions()
  server.register_instance(servod)
  logger.info('Listening on %s port %s' % (options.host, servo_port))
  server.serve_forever()


def main():
  """Main function wrapper to catch exceptions properly"""
  try:
    main_function()
  except KeyboardInterrupt:
    sys.exit(0)
  except ServodError as e:
    print 'Error: ', e.message
    sys.exit(1)


if __name__ == '__main__':
  main()
