# Copyright (c) 2011 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.
"""The experiment file module. It manages the input file of crosperf."""

from __future__ import print_function
import os.path
import re
from settings_factory import SettingsFactory


class ExperimentFile(object):
  """Class for parsing the experiment file format.

  The grammar for this format is:

  experiment = { _FIELD_VALUE_RE | settings }
  settings = _OPEN_SETTINGS_RE
             { _FIELD_VALUE_RE }
             _CLOSE_SETTINGS_RE

  Where the regexes are terminals defined below. This results in an format
  which looks something like:

  field_name: value
  settings_type: settings_name {
    field_name: value
    field_name: value
  }
  """

  # Field regex, e.g. "iterations: 3"
  _FIELD_VALUE_RE = re.compile(r'(\+)?\s*(\w+?)(?:\.(\S+))?\s*:\s*(.*)')
  # Open settings regex, e.g. "label {"
  _OPEN_SETTINGS_RE = re.compile(r'(?:([\w.-]+):)?\s*([\w.-]+)\s*{')
  # Close settings regex.
  _CLOSE_SETTINGS_RE = re.compile(r'}')

  def __init__(self, experiment_file, overrides=None):
    """Construct object from file-like experiment_file.

    Args:
      experiment_file: file-like object with text description of experiment.
      overrides: A settings object that will override fields in other settings.

    Raises:
      Exception: if invalid build type or description is invalid.
    """
    self.all_settings = []
    self.global_settings = SettingsFactory().GetSettings('global', 'global')
    self.all_settings.append(self.global_settings)

    self._Parse(experiment_file)

    for settings in self.all_settings:
      settings.Inherit()
      settings.Validate()
      if overrides:
        settings.Override(overrides)

  def GetSettings(self, settings_type):
    """Return nested fields from the experiment file."""
    res = []
    for settings in self.all_settings:
      if settings.settings_type == settings_type:
        res.append(settings)
    return res

  def GetGlobalSettings(self):
    """Return the global fields from the experiment file."""
    return self.global_settings

  def _ParseField(self, reader):
    """Parse a key/value field."""
    line = reader.CurrentLine().strip()
    match = ExperimentFile._FIELD_VALUE_RE.match(line)
    append, name, _, text_value = match.groups()
    return (name, text_value, append)

  def _ParseSettings(self, reader):
    """Parse a settings block."""
    line = reader.CurrentLine().strip()
    match = ExperimentFile._OPEN_SETTINGS_RE.match(line)
    settings_type = match.group(1)
    if settings_type is None:
      settings_type = ''
    settings_name = match.group(2)
    settings = SettingsFactory().GetSettings(settings_name, settings_type)
    settings.SetParentSettings(self.global_settings)

    while reader.NextLine():
      line = reader.CurrentLine().strip()

      if not line:
        continue
      elif ExperimentFile._FIELD_VALUE_RE.match(line):
        field = self._ParseField(reader)
        settings.SetField(field[0], field[1], field[2])
      elif ExperimentFile._CLOSE_SETTINGS_RE.match(line):
        return settings, settings_type

    raise EOFError('Unexpected EOF while parsing settings block.')

  def _Parse(self, experiment_file):
    """Parse experiment file and create settings."""
    reader = ExperimentFileReader(experiment_file)
    settings_names = {}
    try:
      while reader.NextLine():
        line = reader.CurrentLine().strip()

        if not line:
          continue
        elif ExperimentFile._OPEN_SETTINGS_RE.match(line):
          new_settings, settings_type = self._ParseSettings(reader)
          # We will allow benchmarks with duplicated settings name for now.
          # Further decision will be made when parsing benchmark details in
          # ExperimentFactory.GetExperiment().
          if settings_type != 'benchmark':
            if new_settings.name in settings_names:
              raise SyntaxError(
                  "Duplicate settings name: '%s'." % new_settings.name)
            settings_names[new_settings.name] = True
          self.all_settings.append(new_settings)
        elif ExperimentFile._FIELD_VALUE_RE.match(line):
          field = self._ParseField(reader)
          self.global_settings.SetField(field[0], field[1], field[2])
        else:
          raise IOError('Unexpected line.')
    except Exception, err:
      raise RuntimeError('Line %d: %s\n==> %s' % (reader.LineNo(), str(err),
                                                  reader.CurrentLine(False)))

  def Canonicalize(self):
    """Convert parsed experiment file back into an experiment file."""
    res = ''
    board = ''
    for field_name in self.global_settings.fields:
      field = self.global_settings.fields[field_name]
      if field.assigned:
        res += '%s: %s\n' % (field.name, field.GetString())
      if field.name == 'board':
        board = field.GetString()
    res += '\n'

    for settings in self.all_settings:
      if settings.settings_type != 'global':
        res += '%s: %s {\n' % (settings.settings_type, settings.name)
        for field_name in settings.fields:
          field = settings.fields[field_name]
          if field.assigned:
            res += '\t%s: %s\n' % (field.name, field.GetString())
            if field.name == 'chromeos_image':
              real_file = (
                  os.path.realpath(os.path.expanduser(field.GetString())))
              if real_file != field.GetString():
                res += '\t#actual_image: %s\n' % real_file
            if field.name == 'build':
              chromeos_root_field = settings.fields['chromeos_root']
              if chromeos_root_field:
                chromeos_root = chromeos_root_field.GetString()
              value = field.GetString()
              autotest_field = settings.fields['autotest_path']
              autotest_path = ''
              if autotest_field.assigned:
                autotest_path = autotest_field.GetString()
              image_path, autotest_path = settings.GetXbuddyPath(
                  value, autotest_path, board, chromeos_root, 'quiet')
              res += '\t#actual_image: %s\n' % image_path
              if not autotest_field.assigned:
                res += '\t#actual_autotest_path: %s\n' % autotest_path

        res += '}\n\n'

    return res


class ExperimentFileReader(object):
  """Handle reading lines from an experiment file."""

  def __init__(self, file_object):
    self.file_object = file_object
    self.current_line = None
    self.current_line_no = 0

  def CurrentLine(self, strip_comment=True):
    """Return the next line from the file, without advancing the iterator."""
    if strip_comment:
      return self._StripComment(self.current_line)
    return self.current_line

  def NextLine(self, strip_comment=True):
    """Advance the iterator and return the next line of the file."""
    self.current_line_no += 1
    self.current_line = self.file_object.readline()
    return self.CurrentLine(strip_comment)

  def _StripComment(self, line):
    """Strip comments starting with # from a line."""
    if '#' in line:
      line = line[:line.find('#')] + line[-1]
    return line

  def LineNo(self):
    """Return the current line number."""
    return self.current_line_no
