# Copyright (c) 2013 The ChromiumOS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Manage bundles of flags used for the optimizing of ChromeOS.

Part of the Chrome build flags optimization.

The content of this module is adapted from the Trakhelp JVM project. This module
contains the basic Class Flag and the Class FlagSet. The core abstractions are:

The class Flag, which takes a domain specific language describing how to fill
the flags with values.

The class FlagSet, which contains a number of flags and can create new FlagSets
by mixing with other FlagSets.

The Flag DSL works by replacing value ranges in [x-y] with numbers in the range
x through y.

Examples:
  "foo[0-9]bar" will expand to e.g. "foo5bar".
"""

__author__ = 'yuhenglong@google.com (Yuheng Long)'

import random
import re

#
# This matches a [...] group in the internal representation for a flag
# specification, and is used in "filling out" flags - placing values inside
# the flag_spec.  The internal flag_spec format is like "foo[0]", with
# values filled out like 5; this would be transformed by
# FormattedForUse() into "foo5".
_FLAG_FILLOUT_VALUE_RE = re.compile(r'\[([^\]]*)\]')

# This matches a numeric flag flag=[start-end].
rx = re.compile(r'\[(?P<start>\d+)-(?P<end>\d+)\]')


# Search the numeric flag pattern.
def Search(spec):
  return rx.search(spec)


class NoSuchFileError(Exception):
  """Define an Exception class for user providing invalid input file."""
  pass


def ReadConf(file_name):
  """Parse the configuration file.

  The configuration contains one flag specification in each line.

  Args:
    file_name: The name of the configuration file.

  Returns:
    A list of specs in the configuration file.

  Raises:
    NoSuchFileError: The caller should provide a valid configuration file.
  """

  with open(file_name, 'r') as input_file:
    lines = input_file.readlines()

    return sorted([line.strip() for line in lines if line.strip()])

  raise NoSuchFileError()


class Flag(object):
  """A class representing a particular command line flag argument.

  The Flag consists of two parts: The spec and the value.
  The spec is a definition of the following form: a string with escaped
  sequences of the form [<start>-<end>] where start and end is an positive
  integer for a fillable value.

  An example of a spec is "foo[0-9]".
  There are two kinds of flags, boolean flag and numeric flags. Boolean flags
  can either be turned on or off, which numeric flags can have different
  positive integer values. For example, -finline-limit=[1-1000] is a numeric
  flag and -ftree-vectorize is a boolean flag.

  A (boolean/numeric) flag is not turned on if it is not selected in the
  FlagSet.
  """

  def __init__(self, spec, value=-1):
    self._spec = spec

    # If the value is not specified, generate a random value to use.
    if value == -1:
      # If creating a boolean flag, the value will be 0.
      value = 0

      # Parse the spec's expression for the flag value's numeric range.
      numeric_flag_match = Search(spec)

      # If this is a numeric flag, a value is chosen within start and end, start
      # inclusive and end exclusive.
      if numeric_flag_match:
        start = int(numeric_flag_match.group('start'))
        end = int(numeric_flag_match.group('end'))

        assert start < end
        value = random.randint(start, end)

    self._value = value

  def __eq__(self, other):
    if isinstance(other, Flag):
      return self._spec == other.GetSpec() and self._value == other.GetValue()
    return False

  def __hash__(self):
    return hash(self._spec) + self._value

  def GetValue(self):
    """Get the value for this flag.

    Returns:
     The value.
    """

    return self._value

  def GetSpec(self):
    """Get the spec for this flag.

    Returns:
     The spec.
    """

    return self._spec

  def FormattedForUse(self):
    """Calculate the combination of flag_spec and values.

    For e.g. the flag_spec 'foo[0-9]' and the value equals to 5, this will
    return 'foo5'. The filled out version of the flag is the text string you use
    when you actually want to pass the flag to some binary.

    Returns:
      A string that represent the filled out flag, e.g. the flag with the
      FlagSpec '-X[0-9]Y' and value equals to 5 would return '-X5Y'.
    """

    return _FLAG_FILLOUT_VALUE_RE.sub(str(self._value), self._spec)


class FlagSet(object):
  """A dictionary of Flag objects.

  The flags dictionary stores the spec and flag pair.
  """

  def __init__(self, flag_array):
    # Store the flags as a dictionary mapping of spec -> flag object
    self._flags = dict([(flag.GetSpec(), flag) for flag in flag_array])

  def __eq__(self, other):
    return isinstance(other, FlagSet) and self._flags == other.GetFlags()

  def __hash__(self):
    return sum([hash(flag) for flag in self._flags.values()])

  def __getitem__(self, flag_spec):
    """Get flag with a particular flag_spec.

    Args:
      flag_spec: The flag_spec to find.

    Returns:
      A flag.
    """

    return self._flags[flag_spec]

  def __contains__(self, flag_spec):
    return self._flags.has_key(flag_spec)

  def GetFlags(self):
    return self._flags

  def FormattedForUse(self):
    """Format this for use in an application.

    Returns:
      A list of flags, sorted alphabetically and filled in with the values
      for each flag.
    """

    return sorted([f.FormattedForUse() for f in self._flags.values()])
