# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os
import re

from variants import ALL_VARIANTS
from utils import Freeze

# Possible outcomes
FAIL = "FAIL"
PASS = "PASS"
TIMEOUT = "TIMEOUT"
CRASH = "CRASH"

# Outcomes only for status file, need special handling
FAIL_OK = "FAIL_OK"
FAIL_SLOPPY = "FAIL_SLOPPY"

# Modifiers
SKIP = "SKIP"
SLOW = "SLOW"
NO_VARIANTS = "NO_VARIANTS"
FAIL_PHASE_ONLY = "FAIL_PHASE_ONLY"

ALWAYS = "ALWAYS"

KEYWORDS = {}
for key in [SKIP, FAIL, PASS, CRASH, SLOW, FAIL_OK, NO_VARIANTS, FAIL_SLOPPY,
            ALWAYS, FAIL_PHASE_ONLY]:
  KEYWORDS[key] = key

# Support arches, modes to be written as keywords instead of strings.
VARIABLES = {ALWAYS: True}
for var in ["debug", "release", "big", "little", "android",
            "android_arm", "android_arm64", "android_ia32", "android_x64",
            "arm", "arm64", "ia32", "mips", "mipsel", "mips64", "mips64el",
            "x64", "ppc", "ppc64", "s390", "s390x", "macos", "windows",
            "linux", "aix", "r1", "r2", "r3", "r5", "r6"]:
  VARIABLES[var] = var

# Allow using variants as keywords.
for var in ALL_VARIANTS:
  VARIABLES[var] = var

class StatusFile(object):
  def __init__(self, path, variables):
    """
    _rules:        {variant: {test name: [rule]}}
    _prefix_rules: {variant: {test name prefix: [rule]}}
    """
    with open(path) as f:
      self._rules, self._prefix_rules = ReadStatusFile(f.read(), variables)

  def get_outcomes(self, testname, variant=None):
    """Merges variant dependent and independent rules."""
    outcomes = frozenset()

    for key in set([variant or '', '']):
      rules = self._rules.get(key, {})
      prefix_rules = self._prefix_rules.get(key, {})

      if testname in rules:
        outcomes |= rules[testname]

      for prefix in prefix_rules:
        if testname.startswith(prefix):
          outcomes |= prefix_rules[prefix]

    return outcomes

  def warn_unused_rules(self, tests, check_variant_rules=False):
    """Finds and prints unused rules in status file.

    Rule X is unused when it doesn't apply to any tests, which can also mean
    that all matching tests were skipped by another rule before evaluating X.

    Args:
      tests: list of pairs (testname, variant)
      check_variant_rules: if set variant dependent rules are checked
    """

    if check_variant_rules:
      variants = list(ALL_VARIANTS)
    else:
      variants = ['']
    used_rules = set()

    for testname, variant in tests:
      variant = variant or ''

      if testname in self._rules.get(variant, {}):
        used_rules.add((testname, variant))
        if SKIP in self._rules[variant][testname]:
          continue

      for prefix in self._prefix_rules.get(variant, {}):
        if testname.startswith(prefix):
          used_rules.add((prefix, variant))
          if SKIP in self._prefix_rules[variant][prefix]:
            break

    for variant in variants:
      for rule, value in (
          list(self._rules.get(variant, {}).iteritems()) +
          list(self._prefix_rules.get(variant, {}).iteritems())):
        if (rule, variant) not in used_rules:
          if variant == '':
            variant_desc = 'variant independent'
          else:
            variant_desc = 'variant: %s' % variant
          print 'Unused rule: %s -> %s (%s)' % (rule, value, variant_desc)


def _JoinsPassAndFail(outcomes1, outcomes2):
  """Indicates if we join PASS and FAIL from two different outcome sets and
  the first doesn't already contain both.
  """
  return (
      PASS in outcomes1 and
      not (FAIL in outcomes1 or FAIL_OK in outcomes1) and
      (FAIL in outcomes2 or FAIL_OK in outcomes2)
  )

VARIANT_EXPRESSION = object()

def _EvalExpression(exp, variables):
  """Evaluates expression and returns its result. In case of NameError caused by
  undefined "variant" identifier returns VARIANT_EXPRESSION marker.
  """

  try:
    return eval(exp, variables)
  except NameError as e:
    identifier = re.match("name '(.*)' is not defined", e.message).group(1)
    assert identifier == "variant", "Unknown identifier: %s" % identifier
    return VARIANT_EXPRESSION


def _EvalVariantExpression(
  condition, section, variables, variant, rules, prefix_rules):
  variables_with_variant = dict(variables)
  variables_with_variant["variant"] = variant
  result = _EvalExpression(condition, variables_with_variant)
  assert result != VARIANT_EXPRESSION
  if result is True:
    _ReadSection(
        section,
        variables_with_variant,
        rules[variant],
        prefix_rules[variant],
    )
  else:
    assert result is False, "Make sure expressions evaluate to boolean values"


def _ParseOutcomeList(rule, outcomes, variables, target_dict):
  """Outcome list format: [condition, outcome, outcome, ...]"""

  result = set([])
  if type(outcomes) == str:
    outcomes = [outcomes]
  for item in outcomes:
    if type(item) == str:
      result.add(item)
    elif type(item) == list:
      condition = item[0]
      exp = _EvalExpression(condition, variables)
      assert exp != VARIANT_EXPRESSION, (
        "Nested variant expressions are not supported")
      if exp is False:
        continue

      # Ensure nobody uses an identifier by mistake, like "default",
      # which would evaluate to true here otherwise.
      assert exp is True, "Make sure expressions evaluate to boolean values"

      for outcome in item[1:]:
        assert type(outcome) == str
        result.add(outcome)
    else:
      assert False
  if len(result) == 0:
    return
  if rule in target_dict:
    # A FAIL without PASS in one rule has always precedence over a single
    # PASS (without FAIL) in another. Otherwise the default PASS expectation
    # in a rule with a modifier (e.g. PASS, SLOW) would be joined to a FAIL
    # from another rule (which intended to mark a test as FAIL and not as
    # PASS and FAIL).
    if _JoinsPassAndFail(target_dict[rule], result):
      target_dict[rule] -= set([PASS])
    if _JoinsPassAndFail(result, target_dict[rule]):
      result -= set([PASS])
    target_dict[rule] |= result
  else:
    target_dict[rule] = result


def ReadContent(content):
  return eval(content, KEYWORDS)


def ReadStatusFile(content, variables):
  """Status file format
  Status file := [section]
  section = [CONDITION, section_rules]
  section_rules := {path: outcomes}
  outcomes := outcome | [outcome, ...]
  outcome := SINGLE_OUTCOME | [CONDITION, SINGLE_OUTCOME, SINGLE_OUTCOME, ...]
  """

  # Empty defaults for rules and prefix_rules. Variant-independent
  # rules are mapped by "", others by the variant name.
  rules = {variant: {} for variant in ALL_VARIANTS}
  rules[""] = {}
  prefix_rules = {variant: {} for variant in ALL_VARIANTS}
  prefix_rules[""] = {}

  variables.update(VARIABLES)
  for conditional_section in ReadContent(content):
    assert type(conditional_section) == list
    assert len(conditional_section) == 2
    condition, section = conditional_section
    exp = _EvalExpression(condition, variables)

    # The expression is variant-independent and evaluates to False.
    if exp is False:
      continue

    # The expression is variant-independent and evaluates to True.
    if exp is True:
      _ReadSection(
          section,
          variables,
          rules[''],
          prefix_rules[''],
      )
      continue

    # The expression is variant-dependent (contains "variant" keyword)
    if exp == VARIANT_EXPRESSION:
      # If the expression contains one or more "variant" keywords, we evaluate
      # it for all possible variants and create rules for those that apply.
      for variant in ALL_VARIANTS:
        _EvalVariantExpression(
            condition, section, variables, variant, rules, prefix_rules)
      continue

    assert False, "Make sure expressions evaluate to boolean values"

  return Freeze(rules), Freeze(prefix_rules)


def _ReadSection(section, variables, rules, prefix_rules):
  assert type(section) == dict
  for rule, outcome_list in section.iteritems():
    assert type(rule) == str

    if rule[-1] == '*':
      _ParseOutcomeList(rule[:-1], outcome_list, variables, prefix_rules)
    else:
      _ParseOutcomeList(rule, outcome_list, variables, rules)

JS_TEST_PATHS = {
  'debugger': [[]],
  'inspector': [[]],
  'intl': [[]],
  'message': [[]],
  'mjsunit': [[]],
  'mozilla': [['data']],
  'test262': [['data', 'test'], ['local-tests', 'test']],
  'webkit': [[]],
}

def PresubmitCheck(path):
  with open(path) as f:
    contents = ReadContent(f.read())
  basename = os.path.basename(os.path.dirname(path))
  root_prefix = basename + "/"
  status = {"success": True}
  def _assert(check, message):  # Like "assert", but doesn't throw.
    if not check:
      print("%s: Error: %s" % (path, message))
      status["success"] = False
  try:
    for section in contents:
      _assert(type(section) == list, "Section must be a list")
      _assert(len(section) == 2, "Section list must have exactly 2 entries")
      section = section[1]
      _assert(type(section) == dict,
              "Second entry of section must be a dictionary")
      for rule in section:
        _assert(type(rule) == str, "Rule key must be a string")
        _assert(not rule.startswith(root_prefix),
                "Suite name prefix must not be used in rule keys")
        _assert(not rule.endswith('.js'),
                ".js extension must not be used in rule keys.")
        _assert('*' not in rule or (rule.count('*') == 1 and rule[-1] == '*'),
                "Only the last character of a rule key can be a wildcard")
        if basename in JS_TEST_PATHS  and '*' not in rule:
          _assert(any(os.path.exists(os.path.join(os.path.dirname(path),
                                                  *(paths + [rule + ".js"])))
                      for paths in JS_TEST_PATHS[basename]),
                  "missing file for %s test %s" % (basename, rule))
    return status["success"]
  except Exception as e:
    print e
    return False
