# 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.
"""System configuration module."""
import collections
import logging
import os
import xml.etree.ElementTree


# valid tags in system config xml.  Any others will be ignored
SYSCFG_TAG_LIST = ["map", "control"]
ALLOWABLE_INPUT_TYPES = {"float": float, "int": int, "str": str}

class SystemConfigError(Exception):
  """Error class for SystemConfig."""


class SystemConfig(object):
  """SystemConfig Class.

  System config files describe how to talk to various pieces on the device under
  test.  The system config may be broken up into multiple file to make it easier
  to share configs among similar DUTs.  This class has the support to take in
  multiple SystemConfig files and treat them as one unified structure


  SystemConfig files are written in xml and consist of four main elements

  0. Include : Ability to include other config files

  <include>
    <name>servo_loc.xml</name>
  </include>

  NOTE, All includes in a file WILL be sourced prior to any other elements in
  the XML.

  1. Map : Allow user-friendly naming for things to abstract
  certain things like on=0 for things that are assertive low on
  actual h/w

  <map>
    <name>onoff_i</name>
    <doc>assertive low map for on/off</doc>
    <params on="0" off="1"></params>
  </map>

  2. Control : Bulk of the system file.  These elements are
  typically gpios, adcs, dacs which allow either control or sampling
  of events on the h/w. Controls should have a 1to1 correspondence
  with hardware elements between control system and DUT.

  <control>
    <name>warm_reset</name>
    <doc>Reset the device warmly</doc>
    <params interface="1" drv="gpio" offset="5" map="onoff_i"></params>
  </control>


  TODO(tbroch) Implement sequence or deprecate
  3. Sequence : List of control calls to create a desired
  configuration of h/w.  These could certainly be done by writing
  simple scripts to send individual control calls to the server but
  encapsulating them into the system file should allow for tighter
  control of the sequence ... especially if timing of the sequence
  is paramount.

  <sequence>
    <name>i2c_mux_seq</name>
    <cmdlist>i2c_mux_en:off i2c_mux_add:__arg0__ i2c_mux_en:on</cmdlist>
  </sequence>

  Public Attributes:
    syscfg_dict: 3-deep dictionary created when parsing system files.  Its
        organized as [tag][name][type] where:
        tag: map | control | sequence
        name: string name of tag element
        type: data type of payload either, doc | get | set presently
          doc: string describing the map,control or sequence
          get: a dictionary for getting values from named control
          set: a dictionary for setting values to named control
    hwinit: list of control tuples (name, value) to be initialized in order

  Private Attributes:
    _loaded_xml_files: set of filenames already loaded to avoid sourcing XML
      multiple times.
  """

  def __init__(self):
    """SystemConfig constructor."""
    self._logger = logging.getLogger("SystemConfig")
    self._logger.debug("")
    self.syscfg_dict = collections.defaultdict(dict)
    self.hwinit = []
    self._loaded_xml_files = []

  def find_cfg_file(self, filename):
    """Find the filename for a system XML config file.

    If the provided `filename` names a valid file, use that.
    Otherwise, `filename` must name a file in the 'data'
    subdirectory stored with this module.

    Returns the path selected as described above; if neither of the
    paths names a valid file, return `None`.

    Args:
      filename: string of path to system file ( xml )

    """
    if os.path.isfile(filename):
      return filename
    default_path = os.path.join(os.path.dirname(__file__), "data")
    fullname = os.path.join(default_path, filename)
    if os.path.isfile(fullname):
      return fullname
    return None

  def add_cfg_file(self, filename, name_prefix=None, interface_increment=0):
    """Add system config file to the system config object

    Each design may rely on multiple system files so need to have the facility
    to parse them all.

    For example, we may have a:
    1. default for all controls that are the same for each of the
    control systems
    2. default for a particular DUT system's usage across the
    connector
    3. specific one for particular version of DUT (evt,dvt,mp)
    4. specific one for a one-off rework done to a system

    Special key parameters in config files:
      clobber_ok: signifies this control may _clobber_ an existing definition
        of the same name.  Note, its value is ignored ( clobber_ok='' )

    NOTE, method is recursive when parsing 'include' elements from XML.

    The arguments name_prefix and interface_increment are used to support
    multiple servo micros. The interfaces of the extra servo micros, like
    the one for hammer, are relocated to higher slots. The controls of this
    extra servo micros should be shifted their interface numbers. Adding
    the name prefix avoid conflict with the main servo micro.

    Args:
      filename: string of path to system file ( xml )
      name_prefix: string to prepend to all control names
      interface_increment: number to add to all interfaces

    Raises:
      SystemConfigError: for schema violations, or file not found.
    """
    cfgname = self.find_cfg_file(filename)
    if not cfgname:
      msg = "Unable to find system file %s" % filename
      self._logger.error(msg)
      raise SystemConfigError(msg)

    filename = cfgname
    if (filename, name_prefix, interface_increment) in self._loaded_xml_files:
      self._logger.warn(
          "Already sourced system file (%s, %s, %d).",
          filename, name_prefix, interface_increment)
      return
    self._loaded_xml_files.append((filename, name_prefix, interface_increment))

    self._logger.info("Loading XML config (%s, %s, %d)", filename,
                      name_prefix, interface_increment)
    root = xml.etree.ElementTree.parse(filename).getroot()
    for element in root.findall('include'):
      self.add_cfg_file(element.find('name').text, name_prefix,
                        interface_increment)
    for tag in SYSCFG_TAG_LIST:
      for element in root.findall(tag):
        element_str = xml.etree.ElementTree.tostring(element)
        try:
          name = element.find('name').text
          if tag == 'control' and name_prefix:
            name = name_prefix + '_' + name
        except AttributeError:
          # TODO(tbroch) would rather have lineno but dumping element seems
          # better than nothing.  Utimately a DTD/XSD for the XML schema will
          # catch these anyways.
          raise SystemConfigError("%s: no name ... see XML\n%s" %
                                  (tag, element_str))
        try:
          doc = " ".join(element.find('doc').text.split())
        except AttributeError:
          doc = 'undocumented'
        try:
          alias = element.find('alias').text
        except AttributeError:
          alias = None
        try:
          remap = element.find('remap').text
        except AttributeError:
          remap = None

        if remap:
          try:
            self.syscfg_dict[tag][remap] = self.syscfg_dict[tag][name]
          except KeyError:
            # Sometimes the remap control doesn't exist (e.g. fw_up in servo
            # v4).  Just ignore it and continue on.
            pass
          continue

        get_dict = None
        set_dict = None
        clobber_ok = False
        params_list = element.findall('params')

        # Modify the interface attributes.
        for params in params_list:
          if 'interface' in params.attrib:
            if params.attrib['interface'] != 'servo':
              interface_id = int(params.attrib['interface'])
              params.attrib['interface'] = interface_id + interface_increment

        if len(params_list) == 2:
          assert tag != 'map', "maps have only one params entry"
          for params in params_list:
            if 'cmd' not in params.attrib:
              raise SystemConfigError("%s %s multiple params but no cmd\n%s"
                                      % (tag, name, element_str))
            cmd = params.attrib['cmd']
            if cmd == 'get':
              if get_dict:
                raise SystemConfigError("%s %s multiple get params defined\n%s"
                                        % (tag, name, element_str))
              get_dict = params.attrib
            elif cmd == 'set':
              if set_dict:
                raise SystemConfigError("%s %s multiple set params defined\n%s"
                                        % (tag, name, element_str))
              set_dict = params.attrib
            else:
              raise SystemConfigError("%s %s cmd of 'get'|'set' not found\n%s"
                                      % (tag, name, element_str))
        elif len(params_list) == 1:
          get_dict = params_list[0].attrib
          set_dict = get_dict
        else:
          raise SystemConfigError("%s %s has illegal number of params %d\n%s"
                                  % (tag, name, len(params_list), element_str))

        # Save the control name to the params dicts, such that the driver can
        # refer to it.
        if tag == 'control':
          get_dict['control_name'] = name
          set_dict['control_name'] = name

        clobber_ok = ('clobber_ok' in set_dict or 'clobber_ok' in get_dict)
        if (tag == 'control' and name in self.syscfg_dict[tag] and
            not clobber_ok):
          raise SystemConfigError("Duplicate %s %s without 'clobber_ok' key\n%s"
                                  % (tag, name, element_str))

        if tag == 'map':
          self.syscfg_dict[tag][name] = {'doc':doc, 'map_params':get_dict}
          if alias:
            raise SystemConfigError("No aliases for maps allowed")
          continue

        if 'init' in set_dict:
          hwinit_found = False
          # only allow one hwinit per control
          if clobber_ok:
            for i, (hwinit_name, _) in enumerate(self.hwinit):
              if hwinit_name == name:
                self.hwinit[i] = (name, set_dict['init'])
                hwinit_found = True
                break

          if not hwinit_found:
            self.hwinit.append((name, set_dict['init']))

        if clobber_ok and name in self.syscfg_dict[tag]:
          # it's an existing control
          self.syscfg_dict[tag][name]['get_params'].update(get_dict)
          self.syscfg_dict[tag][name]['set_params'].update(set_dict)
          if doc != 'undocumented':
            self.syscfg_dict[tag][name]['doc'] = doc
        else:
          # it's a new control
          self.syscfg_dict[tag][name] = {'doc':doc, 'get_params':get_dict,
                                         'set_params':set_dict}
        if alias:
          for aliasname in (elem.strip() for elem in alias.split(',')):
            if name_prefix:
              aliasname = name_prefix + '_' + aliasname
            self.syscfg_dict[tag][aliasname] = self.syscfg_dict[tag][name]

  def lookup_control_params(self, name, is_get=True):
    """Lookup & return control parameter dictionary.

    Note, controls must have either one or two set of parameters.  In the case
    of two, the dictionary must contain k=v element of 'type':'get' or
    'type':'set'

    Args:
      name: string of control name to lookup
      isget: boolean of whether params should be for 'get' | 'set'

    Returns:
      control's parameter dictionary for approrpiate get or set

    Raises:
      NameError: if control name not found
      SystemConfigError: if error encountered identifying parameters
    """
    if name not in self.syscfg_dict['control']:
      raise NameError("No control named %s. All controls:\n%s" % (
        name, ','.join(sorted(self.syscfg_dict['control'].keys()))))
    if is_get:
      return self.syscfg_dict['control'][name]['get_params']
    else:
      return self.syscfg_dict['control'][name]['set_params']

  def is_control(self, name):
    """Determine if name is a control or not.

    Args:
      name: string of control name to lookup

    Returns boolean, True if name is control, False otherwise
    """
    return name in self.syscfg_dict['control']

  def get_control_docstring(self, name):
    """Get controls doc string.

    Args:
      name: string of control name to lookup

    Returns:
      doc string of the control
    """
    return self.syscfg_dict['control'][name]['doc']


  def _lookup(self, tag, name_str):
    """Lookup the tag name_str and return dictionary or None if not found.

    Args:
      tag: string of tag (from SYSCFG_TAG_LIST) to look for name_str under.
      name_str: string of name to lookup

    Returns:
      dictionary from syscfg_dict[tag][name_str] or None
    """
    self._logger.debug("lookup of %s %s" % (tag, name_str))
    return self.syscfg_dict[tag].get(name_str)

  def resolve_val(self, params, map_vstr):
    """Resolve string value.

    Values to set the control to can be mapped to symbolic strings for better
    readability.  For example, its difficult to remember assertion levels of
    various gpios.  Maps allow things like 'reset:on'.  Also provides
    abstraction so that assertion level doesn't have to be exposed.

    Args:
      params: parameters dictionary for control
      map_vstr: string thats acceptable values are:
          an int (can be "DECIMAL", "0xHEX", 0OCT", or "0bBINARY".
          a floating point value.
          an alphanumeric which is key in the corresponding map dictionary.

    Returns:
      Resolved value as float or int

    Raises:
      SystemConfigError: mapping issues found
    """
    if 'input_type' in params:
      if params['input_type'] in ALLOWABLE_INPUT_TYPES:
        input_type = ALLOWABLE_INPUT_TYPES[params['input_type']]
        return input_type(map_vstr)
      else:
        self._logger.error('Unrecognized input type.')
    else:
      # TODO(tbroch): deprecate below once all controls have input_type params
      try:
        return int(str(map_vstr), 0)
      except ValueError:
        pass
      try:
        return float(str(map_vstr))
      except ValueError:
        pass

    # its a map
    if 'map' not in params:
      raise SystemConfigError("No map for control but value is a string")
    map_dict = self._lookup("map", params['map'])
    if map_dict is None:
      raise SystemConfigError("Map %s isn't defined" % params['map'])
    try:
      map_value = map_dict['map_params'][map_vstr]
    except KeyError:
      raise SystemConfigError(("Map %s doesn't contain key %s\n" +
                               "Try one of -> '%s'") %
                              (params['map'], map_vstr,
                               "', '".join(map_dict['map_params'].keys())))
    # TODO(tbroch) likely that maps are only integers but what if ...
    return int(map_value, 0)

  def _Fmt_hex(self, int_val):
    """Format integer into hex.

    Args:
      int_val: integer to be formatted into hex string

    Returns:
      string of integer in hex format
    """
    return hex(int_val)

  def reformat_val(self, params, value):
    """Reformat value.

    Formatting determined via:
      1. if has map, then remap
      2. else if has fmt param, use that function
      3. else, just convert to str

    Args:
      params: parameter dictionary for control
      value: value to reformat

    Returns:
      formatted string value.

    Raises:
      SystemConfigError: errors using formatting param
    """
    reformat_value = str(value)
    if 'map' in params:
      map_dict = self._lookup("map", params['map'])
      if map_dict:
        for keyname, val in map_dict['map_params'].iteritems():
          if val == reformat_value:
            reformat_value = keyname
            break
    elif 'fmt' in params:
      fmt = params['fmt']
      try:
        func = getattr(self, "_Fmt_%s" % fmt)
      except AttributeError:
        raise SystemConfigError("Unrecognized format %s" % fmt)
      try:
        reformat_value = func(value)
      except Exception:
        raise SystemConfigError("Problem executing format %s" % fmt)
    return reformat_value

  def display_config(self, tag=None):
    """Display human-readable values of map, control, or sequence.

    Args:
      tag  : string of either 'map' | 'control' | 'sequence' or None for all

    Returns:
      string to be displayed.
    """
    rsp = []
    if tag is None:
      tag_list = SYSCFG_TAG_LIST
    else:
      tag_list = [tag]
    for tag in sorted(tag_list):

      rsp.append("*************")
      rsp.append("* " + tag.upper())
      rsp.append("*************")
      max_len = 0
      max_len = max(len(name) for name in self.syscfg_dict[tag].iterkeys())
      dashes = '-' * max_len
      for name in sorted(self.syscfg_dict[tag].iterkeys()):
        item_dict = self.syscfg_dict[tag][name]
        padded_name = "%-*s" % (max_len, name)
        rsp.append("%s DOC: %s" % (padded_name, item_dict['doc']))
        if tag == 'map':
          rsp.append("%s MAP: %s" %(dashes, str(item_dict['map_params'])))
        else:
          rsp.append("%s GET: %s" %(dashes, str(item_dict['get_params'])))
          rsp.append("%s SET: %s" %(dashes, str(item_dict['set_params'])))

    return "\n".join(rsp)

def test():
  """Integration test.

  TODO(tbroch) Enhance integration test and add unittest (see mox)
  """
  logging.basicConfig(level=logging.DEBUG,
                      format="%(asctime)s - %(name)s - " +
                      "%(levelname)s - %(message)s")
  scfg = SystemConfig()
  # TODO(tbroch) make this a comprenhensive test xml file
  scfg.add_cfg_file(os.path.join("data", "servo.xml"))
  scfg.display_config()

  control_dict = scfg._lookup('control', 'goog_rec_mode')
  # checking mapping functionality
  control_params = control_dict['get_params']
  control_params = control_dict['set_params']
  if 'map' in control_params:
    map_name = control_params['map']
    map_dict = scfg._lookup('map', map_name)
    if not map_dict:
      raise Exception("Unable to find map %s", map_name)

    logging.info("")
    for keyname, val in map_dict['map_params'].iteritems():
      resolved_val = str(scfg.resolve_val(control_params, keyname))
      if resolved_val != val:
        logging.error("resolve failed for %s -> %s != %s", keyname, val,
                      resolved_val)

      # try re-mapping
      reformat_val = scfg.reformat_val(control_params, int(val))
      reformat_val = scfg.reformat_val(control_params, val)
      if reformat_val != keyname:
        logging.error("reformat failed for %s -> %s != %s", val, keyname,
                      reformat_val)


if __name__ == '__main__':
  test()
