# Copyright (C) 2010 Google Inc. 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.

"""A helper class for reading in and dealing with tests expectations
for layout tests.
"""

import logging
import re
import sys

from webkitpy.common.iteration_compatibility import iteritems, itervalues
from webkitpy.layout_tests.models.test_configuration import TestConfigurationConverter

_log = logging.getLogger(__name__)


# Test expectation and modifier constants.
#
# FIXME: range() starts with 0 which makes if expectation checks harder
# as PASS is 0.
(PASS, FAIL, TEXT, IMAGE, IMAGE_PLUS_TEXT, AUDIO, TIMEOUT, CRASH, SKIP, WONTFIX,
 SLOW, LEAK, DUMPJSCONSOLELOGINSTDERR, REBASELINE, MISSING, FLAKY, NOW, NONE) = range(18)

# FIXME: Perhas these two routines should be part of the Port instead?
BASELINE_SUFFIX_LIST = ('png', 'wav', 'txt')


class ParseError(Exception):
    def __init__(self, warnings):
        super(ParseError, self).__init__()
        self.warnings = warnings

    def __str__(self):
        return '\n'.join(map(str, self.warnings))

    def __repr__(self):
        return 'ParseError(warnings=%s)' % self.warnings


class TestExpectationWarning(object):
    def __init__(self, filename, line_number, line, error, test=None):
        self.filename = filename
        self.line_number = line_number
        self.line = line
        self.error = error
        self.test = test

        self.related_files = {}

    def __str__(self):
        return '{}:{} {} {}'.format(self.filename, self.line_number, self.error, self.test if self.test else self.line)


class TestExpectationParser(object):
    """Provides parsing facilities for lines in the test_expectation.txt file."""

    BUG_MODIFIER_PREFIX = 'bug'
    BUG_MODIFIER_REGEX = 'bug\d+'
    REBASELINE_MODIFIER = 'rebaseline'
    PASS_EXPECTATION = 'pass'
    SKIP_MODIFIER = 'skip'
    SLOW_MODIFIER = 'slow'
    DUMPJSCONSOLELOGINSTDERR_MODIFIER = 'dumpjsconsoleloginstderr'
    WONTFIX_MODIFIER = 'wontfix'

    TIMEOUT_EXPECTATION = 'timeout'

    MISSING_BUG_WARNING = 'Test lacks BUG modifier.'

    def __init__(self, port, full_test_list, allow_rebaseline_modifier, shorten_filename=lambda x: x):
        self._port = port
        self._test_configuration_converter = TestConfigurationConverter(set(port.all_test_configurations()), port.configuration_specifier_macros())
        if full_test_list is None:
            self._full_test_list = None
        else:
            self._full_test_list = set(full_test_list)
        self._allow_rebaseline_modifier = allow_rebaseline_modifier
        self._shorten_filename = shorten_filename

    def parse(self, filename, expectations_string):
        expectation_lines = []
        line_number = 0
        for line in expectations_string.split("\n"):
            line_number += 1
            test_expectation = self._tokenize_line(filename, line, line_number)
            self._parse_line(test_expectation)
            expectation_lines.append(test_expectation)
        return expectation_lines

    def expectation_for_skipped_test(self, test_name):
        if not self._port.test_exists(test_name):
            _log.warning('The following test %s from the Skipped list doesn\'t exist' % test_name)
        expectation_line = TestExpectationLine()
        expectation_line.original_string = test_name
        expectation_line.modifiers = [TestExpectationParser.SKIP_MODIFIER]
        # FIXME: It's not clear what the expectations for a skipped test should be; the expectations
        # might be different for different entries in a Skipped file, or from the command line, or from
        # only running parts of the tests. It's also not clear if it matters much.
        expectation_line.modifiers.append(TestExpectationParser.WONTFIX_MODIFIER)
        expectation_line.name = test_name
        # FIXME: we should pass in a more descriptive string here.
        expectation_line.filename = '<Skipped file>'
        expectation_line.line_number = 0
        expectation_line.expectations = [TestExpectationParser.PASS_EXPECTATION]
        expectation_line.not_applicable_to_current_platform = True
        self._parse_line(expectation_line)
        return expectation_line

    def _parse_line(self, expectation_line):
        if not expectation_line.name:
            return

        if not self._check_test_exists(expectation_line):
            return

        expectation_line.is_file = self._port.test_isfile(expectation_line.name)
        if expectation_line.is_file:
            expectation_line.path = expectation_line.name
        else:
            expectation_line.path = self._port.normalize_test_name(expectation_line.name)

        self._collect_matching_tests(expectation_line)

        self._parse_modifiers(expectation_line)
        self._parse_expectations(expectation_line)

    def _parse_modifiers(self, expectation_line):
        has_wontfix = False
        has_bugid = False
        parsed_specifiers = set()

        modifiers = [modifier.lower() for modifier in expectation_line.modifiers]
        expectations = [expectation.lower() for expectation in expectation_line.expectations]

        if self.SLOW_MODIFIER in modifiers and self.TIMEOUT_EXPECTATION in expectations:
            expectation_line.warnings.append('A test can not be both SLOW and TIMEOUT. If it times out indefinitely, then it should be just TIMEOUT.')

        for modifier in modifiers:
            if modifier in TestExpectations.MODIFIERS:
                expectation_line.parsed_modifiers.append(modifier)
                if modifier == self.WONTFIX_MODIFIER:
                    has_wontfix = True
            elif modifier.startswith(self.BUG_MODIFIER_PREFIX):
                has_bugid = True
                if re.match(self.BUG_MODIFIER_REGEX, modifier):
                    expectation_line.warnings.append('BUG\d+ is not allowed, must be one of BUGWK\d+, or a non-numeric bug identifier.')
                else:
                    expectation_line.parsed_bug_modifiers.append(modifier)
            else:
                parsed_specifiers.add(modifier)

        if not expectation_line.parsed_bug_modifiers and not has_wontfix and not has_bugid and self._port.warn_if_bug_missing_in_test_expectations():
            expectation_line.warnings.append(self.MISSING_BUG_WARNING)

        if self._allow_rebaseline_modifier and self.REBASELINE_MODIFIER in modifiers:
            expectation_line.warnings.append('REBASELINE should only be used for running rebaseline.py. Cannot be checked in.')

        expectation_line.matching_configurations = self._test_configuration_converter.to_config_set(parsed_specifiers, expectation_line.warnings)

    def _parse_expectations(self, expectation_line):
        result = set()
        for part in expectation_line.expectations:
            expectation = TestExpectations.expectation_from_string(part)
            if expectation is None:  # Careful, PASS is currently 0.
                expectation_line.warnings.append('Unsupported expectation: %s' % part)
                continue
            result.add(expectation)
        expectation_line.parsed_expectations = result

    def _check_test_exists(self, expectation_line):
        # WebKit's way of skipping tests is to add a -disabled suffix.
        # So we should consider the path existing if the path or the
        # -disabled version exists.
        if not self._port.test_exists(expectation_line.name) and not self._port.test_exists(expectation_line.name + '-disabled'):
            # Log a warning here since you hit this case any
            # time you update TestExpectations without syncing
            # the LayoutTests directory
            expectation_line.warnings.append('Path does not exist.')
            expected_path = self._shorten_filename(self._port.abspath_for_test(expectation_line.name))
            expectation_line.related_files[expected_path] = None
            return False
        return True

    def _collect_matching_tests(self, expectation_line):
        """Convert the test specification to an absolute, normalized
        path and make sure directories end with the OS path separator."""

        if not self._full_test_list:
            expectation_line.matching_tests = [expectation_line.path]
            return

        if not expectation_line.is_file:
            # this is a test category, return all the tests of the category.
            expectation_line.matching_tests = [test for test in self._full_test_list if test.startswith(expectation_line.path)]
            return

        # this is a test file, do a quick check if it's in the
        # full test suite.
        if expectation_line.path in self._full_test_list:
            expectation_line.matching_tests.append(expectation_line.path)

    # FIXME: Update the original modifiers and remove this once the old syntax is gone.
    _configuration_tokens_list = [
        'SnowLeopard', 'Lion', 'MountainLion', 'Mavericks', 'Yosemite', 'ElCapitan', # Legacy macOS
        'Mac', 'Sierra', 'HighSierra', 'Mojave', 'Catalina',
        'Win', 'XP', 'Vista', 'Win7',
        'Linux',
        'Android',
        'Release',
        'Debug',
    ]

    _configuration_tokens = dict((token, token.upper()) for token in _configuration_tokens_list)
    _inverted_configuration_tokens = dict((value, name) for name, value in _configuration_tokens.items())

    # FIXME: Update the original modifiers list and remove this once the old syntax is gone.
    _expectation_tokens = {
        'Crash': 'CRASH',
        'DumpJSConsoleLogInStdErr': 'DUMPJSCONSOLELOGINSTDERR',
        'Failure': 'FAIL',
        'ImageOnlyFailure': 'IMAGE',
        'Leak': 'LEAK',
        'Missing': 'MISSING',
        'Pass': 'PASS',
        'Rebaseline': 'REBASELINE',
        'Skip': 'SKIP',
        'Slow': 'SLOW',
        'Timeout': 'TIMEOUT',
        'WontFix': 'WONTFIX',
    }

    _inverted_expectation_tokens = dict([(value, name) for name, value in _expectation_tokens.items()] +
                                        [('TEXT', 'Failure'), ('IMAGE+TEXT', 'Failure'), ('AUDIO', 'Failure')])

    # FIXME: Seems like these should be classmethods on TestExpectationLine instead of TestExpectationParser.
    @classmethod
    def _tokenize_line(cls, filename, expectation_string, line_number):
        """Tokenizes a line from TestExpectations and returns an unparsed TestExpectationLine instance using the old format.

        The new format for a test expectation line is:

        [[bugs] [ "[" <configuration modifiers> "]" <name> [ "[" <expectations> "]" ["#" <comment>]

        Any errant whitespace is not preserved.

        """
        expectation_line = TestExpectationLine()
        expectation_line.original_string = expectation_string
        expectation_line.filename = filename
        expectation_line.line_number = line_number

        comment_index = expectation_string.find("#")
        if comment_index == -1:
            comment_index = len(expectation_string)
        else:
            expectation_line.comment = expectation_string[comment_index + 1:]

        remaining_string = re.sub(r"\s+", " ", expectation_string[:comment_index].strip())
        if len(remaining_string) == 0:
            return expectation_line

        # special-case parsing this so that we fail immediately instead of treating this as a test name
        if remaining_string.startswith('//'):
            expectation_line.warnings = ['use "#" instead of "//" for comments']
            return expectation_line

        bugs = []
        modifiers = []
        name = None
        expectations = []
        warnings = []

        WEBKIT_BUG_PREFIX = 'webkit.org/b/'

        tokens = remaining_string.split()
        state = 'start'
        for token in tokens:
            if token.startswith(WEBKIT_BUG_PREFIX) or token.startswith('Bug('):
                if state != 'start':
                    warnings.append('"%s" is not at the start of the line.' % token)
                    break
                if token.startswith(WEBKIT_BUG_PREFIX):
                    bugs.append(token.replace(WEBKIT_BUG_PREFIX, 'BUGWK'))
                else:
                    match = re.match('Bug\((\w+)\)$', token)
                    if not match:
                        warnings.append('unrecognized bug identifier "%s"' % token)
                        break
                    else:
                        bugs.append('BUG' + match.group(1).upper())
            elif token.startswith('BUG'):
                warnings.append('unrecognized old-style bug identifier "%s"' % token)
                break
            elif token == '[':
                if state == 'start':
                    state = 'configuration'
                elif state == 'name_found':
                    state = 'expectations'
                else:
                    warnings.append('unexpected "["')
                    break
            elif token == ']':
                if state == 'configuration':
                    state = 'name'
                elif state == 'expectations':
                    state = 'done'
                else:
                    warnings.append('unexpected "]"')
                    break
            elif token in ('//', ':', '='):
                warnings.append('"%s" is not legal in the new TestExpectations syntax.' % token)
                break
            elif state == 'configuration':
                modifiers.append(cls._configuration_tokens.get(token, token))
            elif state == 'expectations':
                if token in ('Rebaseline', 'Skip', 'Slow', 'WontFix', 'DumpJSConsoleLogInStdErr'):
                    modifiers.append(token.upper())
                elif token not in cls._expectation_tokens:
                    warnings.append('Unrecognized expectation "%s"' % token)
                else:
                    expectations.append(cls._expectation_tokens.get(token, token))
            elif state == 'name_found':
                warnings.append('expecting "[", "#", or end of line instead of "%s"' % token)
                break
            else:
                name = token
                state = 'name_found'

        if not warnings:
            if not name:
                warnings.append('Did not find a test name.')
            elif state not in ('name_found', 'done'):
                warnings.append('Missing a "]"')

        if 'WONTFIX' in modifiers and 'SKIP' not in modifiers and not expectations:
            modifiers.append('SKIP')

        if 'SKIP' in modifiers and expectations:
            # FIXME: This is really a semantic warning and shouldn't be here. Remove when we drop the old syntax.
            warnings.append('A test marked Skip must not have other expectations.')
        elif not expectations:
            # FIXME: We can probably simplify this adding 'SKIP' if modifiers is empty
            if 'SKIP' not in modifiers and 'REBASELINE' not in modifiers and 'SLOW' not in modifiers and 'DUMPJSCONSOLELOGINSTDERR' not in modifiers:
                modifiers.append('SKIP')
            expectations = ['PASS']

        # FIXME: expectation line should just store bugs and modifiers separately.
        expectation_line.modifiers = bugs + modifiers
        expectation_line.expectations = expectations
        expectation_line.name = name
        expectation_line.warnings = warnings
        return expectation_line

    @classmethod
    def _split_space_separated(cls, space_separated_string):
        """Splits a space-separated string into an array."""
        return [part.strip() for part in space_separated_string.strip().split(' ')]


class TestExpectationLine(object):
    """Represents a line in test expectations file."""

    def __init__(self):
        """Initializes a blank-line equivalent of an expectation."""
        self.original_string = None
        self.filename = None  # this is the path to the expectations file for this line
        self.line_number = None
        self.name = None  # this is the path in the line itself
        self.path = None  # this is the normpath of self.name
        self.modifiers = []
        self.parsed_modifiers = []
        self.parsed_bug_modifiers = []
        self.matching_configurations = set()
        self.expectations = []
        self.parsed_expectations = set()
        self.comment = None
        self.matching_tests = []
        self.warnings = []
        self.related_files = {}  # Dictionary of files to lines number in that file which may have caused the list of warnings.
        self.not_applicable_to_current_platform = False

    def __str__(self):
        return self.to_string(None)

    def is_invalid(self):
        return self.warnings and self.warnings != [TestExpectationParser.MISSING_BUG_WARNING]

    def is_flaky(self):
        return len(self.parsed_expectations) > 1

    @property
    def expected_behavior(self):
        expectations = self.expectations[:]
        if "SLOW" in self.modifiers:
            expectations += ["SLOW"]

        if "SKIP" in self.modifiers:
            expectations = ["SKIP"]
        elif "WONTFIX" in self.modifiers:
            expectations = ["WONTFIX"]
        elif "CRASH" in self.modifiers:
            expectations += ["CRASH"]

        return expectations

    @staticmethod
    def create_passing_expectation(test):
        expectation_line = TestExpectationLine()
        expectation_line.name = test
        expectation_line.path = test
        expectation_line.parsed_expectations = set([PASS])
        expectation_line.expectations = ['PASS']
        expectation_line.matching_tests = [test]
        return expectation_line

    def to_string(self, test_configuration_converter, include_modifiers=True, include_expectations=True, include_comment=True):
        parsed_expectation_to_string = dict([[parsed_expectation, expectation_string] for expectation_string, parsed_expectation in TestExpectations.EXPECTATIONS.items()])

        if self.is_invalid():
            return self.original_string or ''

        if self.name is None:
            return '' if self.comment is None else "#%s" % self.comment

        if test_configuration_converter and self.parsed_bug_modifiers:
            specifiers_list = test_configuration_converter.to_specifiers_list(self.matching_configurations)
            result = []
            for specifiers in specifiers_list:
                # FIXME: this is silly that we join the modifiers and then immediately split them.
                modifiers = self._serialize_parsed_modifiers(test_configuration_converter, specifiers).split()
                expectations = self._serialize_parsed_expectations(parsed_expectation_to_string).split()
                result.append(self._format_line(modifiers, self.name, expectations, self.comment))
            return "\n".join(result) if result else None

        return self._format_line(self.modifiers, self.name, self.expectations, self.comment,
            include_modifiers, include_expectations, include_comment)

    def to_csv(self):
        # Note that this doesn't include the comments.
        return '%s,%s,%s' % (self.name, ' '.join(self.modifiers), ' '.join(self.expectations))

    def _serialize_parsed_expectations(self, parsed_expectation_to_string):
        result = []
        for index in TestExpectations.EXPECTATION_ORDER:
            if index in self.parsed_expectations:
                result.append(parsed_expectation_to_string[index])
        return ' '.join(result)

    def _serialize_parsed_modifiers(self, test_configuration_converter, specifiers):
        result = []
        if self.parsed_bug_modifiers:
            result.extend(sorted(self.parsed_bug_modifiers))
        result.extend(sorted(self.parsed_modifiers))
        result.extend(test_configuration_converter.specifier_sorter().sort_specifiers(specifiers))
        return ' '.join(result)

    @staticmethod
    def _format_line(modifiers, name, expectations, comment, include_modifiers=True, include_expectations=True, include_comment=True):
        bugs = []
        new_modifiers = []
        new_expectations = []
        for modifier in modifiers:
            modifier = modifier.upper()
            if modifier.startswith('BUGWK'):
                bugs.append('webkit.org/b/' + modifier.replace('BUGWK', ''))
            elif modifier.startswith('BUG'):
                # FIXME: we should preserve case once we can drop the old syntax.
                bugs.append('Bug(' + modifier[3:].lower() + ')')
            elif modifier in ('SLOW', 'SKIP', 'REBASELINE', 'WONTFIX', 'DUMPJSCONSOLELOGINSTDERR'):
                new_expectations.append(TestExpectationParser._inverted_expectation_tokens.get(modifier))
            else:
                new_modifiers.append(TestExpectationParser._inverted_configuration_tokens.get(modifier, modifier))

        for expectation in expectations:
            expectation = expectation.upper()
            new_expectations.append(TestExpectationParser._inverted_expectation_tokens.get(expectation, expectation))

        result = ''
        if include_modifiers and (bugs or new_modifiers):
            if bugs:
                result += ' '.join(bugs) + ' '
            if new_modifiers:
                result += '[ %s ] ' % ' '.join(new_modifiers)
        result += name
        if include_expectations and new_expectations and set(new_expectations) != set(['Skip', 'Pass']):
            result += ' [ %s ]' % ' '.join(sorted(set(new_expectations)))
        if include_comment and comment is not None:
            result += " #%s" % comment
        return result


# FIXME: Refactor API to be a proper CRUD.
class TestExpectationsModel(object):
    """Represents relational store of all expectations and provides CRUD semantics to manage it."""

    def __init__(self, shorten_filename=lambda x: x):
        # Maps a test to its list of expectations.
        self._test_to_expectations = {}

        # Maps a test to list of its modifiers (string values)
        self._test_to_modifiers = {}

        # Maps a test to a TestExpectationLine instance.
        self._test_to_expectation_line = {}

        self._modifier_to_tests = self._dict_of_sets(TestExpectations.MODIFIERS)
        self._expectation_to_tests = self._dict_of_sets(TestExpectations.EXPECTATIONS)
        self._timeline_to_tests = self._dict_of_sets(TestExpectations.TIMELINES)
        self._result_type_to_tests = self._dict_of_sets(TestExpectations.RESULT_TYPES)

        self._shorten_filename = shorten_filename

    def _dict_of_sets(self, strings_to_constants):
        """Takes a dict of strings->constants and returns a dict mapping
        each constant to an empty set."""
        d = {}
        for c in strings_to_constants.values():
            d[c] = set()
        return d

    def get_test_set(self, modifier, expectation=None, include_skips=True):
        if expectation is None:
            tests = self._modifier_to_tests[modifier]
        else:
            tests = (self._expectation_to_tests[expectation] &
                self._modifier_to_tests[modifier])

        if not include_skips:
            tests = tests - self.get_test_set(SKIP, expectation)

        return tests

    def get_test_set_for_keyword(self, keyword):
        # FIXME: get_test_set() is an awkward public interface because it requires
        # callers to know the difference between modifiers and expectations. We
        # should replace that with this where possible.
        expectation_enum = TestExpectations.EXPECTATIONS.get(keyword.lower(), None)
        if expectation_enum is not None:
            return self._expectation_to_tests[expectation_enum]
        modifier_enum = TestExpectations.MODIFIERS.get(keyword.lower(), None)
        if modifier_enum is not None:
            return self._modifier_to_tests[modifier_enum]

        # We must not have an index on this modifier.
        matching_tests = set()
        for test, modifiers in iteritems(self._test_to_modifiers):
            if keyword.lower() in modifiers:
                matching_tests.add(test)
        return matching_tests

    def get_tests_with_result_type(self, result_type):
        return self._result_type_to_tests[result_type]

    def get_tests_with_timeline(self, timeline):
        return self._timeline_to_tests[timeline]

    def get_modifiers(self, test):
        """This returns modifiers for the given test (the modifiers plus the BUGXXXX identifier). This is used by the LTTF dashboard."""
        return self._test_to_modifiers[test]

    def has_modifier(self, test, modifier):
        return test in self._modifier_to_tests[modifier]

    def has_keyword(self, test, keyword):
        return (keyword.upper() in self.get_expectations_string(test) or
                keyword.lower() in self.get_modifiers(test))

    def has_test(self, test):
        return test in self._test_to_expectation_line

    def get_expectation_line(self, test):
        return self._test_to_expectation_line.get(test)

    def get_expectations(self, test):
        return self._test_to_expectations[test]

    def get_expectations_or_pass(self, test):
        try:
            return self.get_expectations(test)
        except:
            return set([PASS])

    def expectations_to_string(self, expectations):
        retval = []

        for expectation in expectations:
            retval.append(self.expectation_to_string(expectation))

        return " ".join(retval)

    def get_expectations_string(self, test):
        """Returns the expectations for the given test as an uppercase string.
        If there are no expectations for the test, then "PASS" is returned."""
        try:
            expectations = self.get_expectations(test)
        except:
            return "PASS"
        retval = []

        for expectation in expectations:
            retval.append(self.expectation_to_string(expectation))

        return " ".join(retval)

    def expectation_to_string(self, expectation):
        """Return the uppercased string equivalent of a given expectation."""
        for item in TestExpectations.EXPECTATIONS.items():
            if item[1] == expectation:
                return item[0].upper()
        raise ValueError(expectation)

    def add_expectation_line(self, expectation_line, in_skipped=False):
        """Returns a list of warnings encountered while matching modifiers."""

        if expectation_line.is_invalid():
            return

        for test in expectation_line.matching_tests:
            if not in_skipped and self._already_seen_better_match(test, expectation_line):
                continue

            self._clear_expectations_for_test(test)
            self._test_to_expectation_line[test] = expectation_line
            self._add_test(test, expectation_line)

    def _add_test(self, test, expectation_line):
        """Sets the expected state for a given test.

        This routine assumes the test has not been added before. If it has,
        use _clear_expectations_for_test() to reset the state prior to
        calling this."""
        self._test_to_expectations[test] = expectation_line.parsed_expectations
        for expectation in expectation_line.parsed_expectations:
            self._expectation_to_tests[expectation].add(test)

        self._test_to_modifiers[test] = expectation_line.modifiers
        for modifier in expectation_line.parsed_modifiers:
            mod_value = TestExpectations.MODIFIERS[modifier]
            self._modifier_to_tests[mod_value].add(test)

        if TestExpectationParser.WONTFIX_MODIFIER in expectation_line.parsed_modifiers:
            self._timeline_to_tests[WONTFIX].add(test)
        else:
            self._timeline_to_tests[NOW].add(test)

        if TestExpectationParser.SKIP_MODIFIER in expectation_line.parsed_modifiers:
            self._result_type_to_tests[SKIP].add(test)
        elif expectation_line.parsed_expectations == set([PASS]):
            self._result_type_to_tests[PASS].add(test)
        elif expectation_line.is_flaky():
            self._result_type_to_tests[FLAKY].add(test)
        else:
            # FIXME: What is this?
            self._result_type_to_tests[FAIL].add(test)

    def _clear_expectations_for_test(self, test):
        """Remove prexisting expectations for this test.
        This happens if we are seeing a more precise path
        than a previous listing.
        """
        if self.has_test(test):
            self._test_to_expectations.pop(test, '')
            self._remove_from_sets(test, self._expectation_to_tests)
            self._remove_from_sets(test, self._modifier_to_tests)
            self._remove_from_sets(test, self._timeline_to_tests)
            self._remove_from_sets(test, self._result_type_to_tests)

    def _remove_from_sets(self, test, dict_of_sets_of_tests):
        """Removes the given test from the sets in the dictionary.

        Args:
          test: test to look for
          dict: dict of sets of files"""
        for set_of_tests in itervalues(dict_of_sets_of_tests):
            if test in set_of_tests:
                set_of_tests.remove(test)

    def _already_seen_better_match(self, test, expectation_line):
        """Returns whether we've seen a better match already in the file.

        Returns True if we've already seen a expectation_line.name that matches more of the test
            than this path does
        """
        # FIXME: See comment below about matching test configs and specificity.
        if not self.has_test(test):
            # We've never seen this test before.
            return False

        prev_expectation_line = self._test_to_expectation_line[test]

        if prev_expectation_line.filename != expectation_line.filename:
            # We've moved on to a new expectation file, which overrides older ones.
            return False

        if len(prev_expectation_line.path) > len(expectation_line.path):
            # The previous path matched more of the test.
            return True

        if len(prev_expectation_line.path) < len(expectation_line.path):
            # This path matches more of the test.
            return False

        # At this point we know we have seen a previous exact match on this
        # base path, so we need to check the two sets of modifiers.

        # FIXME: This code was originally designed to allow lines that matched
        # more modifiers to override lines that matched fewer modifiers.
        # However, we currently view these as errors.
        #
        # To use the "more modifiers wins" policy, change the errors for overrides
        # to be warnings and return False".
        shortened_expectation_filename = self._shorten_filename(expectation_line.filename)
        shortened_previous_expectation_filename = self._shorten_filename(prev_expectation_line.filename)

        if prev_expectation_line.matching_configurations == expectation_line.matching_configurations:
            expectation_line.warnings.append('Duplicate or ambiguous entry lines %s:%d and %s:%d.' % (
                shortened_previous_expectation_filename, prev_expectation_line.line_number,
                shortened_expectation_filename, expectation_line.line_number))

        elif prev_expectation_line.matching_configurations >= expectation_line.matching_configurations:
            expectation_line.warnings.append('More specific entry for %s on line %s:%d overrides line %s:%d.' % (expectation_line.name,
                shortened_previous_expectation_filename, prev_expectation_line.line_number,
                shortened_expectation_filename, expectation_line.line_number))
            # FIXME: return False if we want more specific to win.

        elif prev_expectation_line.matching_configurations <= expectation_line.matching_configurations:
            expectation_line.warnings.append('More specific entry for %s on line %s:%d overrides line %s:%d.' % (expectation_line.name,
                shortened_expectation_filename, expectation_line.line_number,
                shortened_previous_expectation_filename, prev_expectation_line.line_number))

        elif prev_expectation_line.matching_configurations & expectation_line.matching_configurations:
            expectation_line.warnings.append('Entries for %s on lines %s:%d and %s:%d match overlapping sets of configurations.' % (expectation_line.name,
                shortened_previous_expectation_filename, prev_expectation_line.line_number,
                shortened_expectation_filename, expectation_line.line_number))

        else:
            # Configuration sets are disjoint.
            return False

        # Missing files will be 'None'. It should be impossible to have a missing file which also has a line associated with it.
        assert shortened_previous_expectation_filename not in expectation_line.related_files or expectation_line.related_files[shortened_previous_expectation_filename] is not None
        expectation_line.related_files[shortened_previous_expectation_filename] = expectation_line.related_files.get(shortened_previous_expectation_filename, [])
        expectation_line.related_files[shortened_previous_expectation_filename].append(prev_expectation_line.line_number)

        assert shortened_expectation_filename not in prev_expectation_line.related_files or prev_expectation_line.related_files[shortened_expectation_filename] is not None
        prev_expectation_line.related_files[shortened_expectation_filename] = prev_expectation_line.related_files.get(shortened_expectation_filename, [])
        prev_expectation_line.related_files[shortened_expectation_filename].append(expectation_line.line_number)

        return True


class TestExpectations(object):
    """Test expectations consist of lines with specifications of what
    to expect from layout test cases. The test cases can be directories
    in which case the expectations apply to all test cases in that
    directory and any subdirectory. The format is along the lines of:

      LayoutTests/js/fixme.js [ Failure ]
      LayoutTests/js/flaky.js [ Failure Pass ]
      LayoutTests/js/crash.js [ Crash Failure Pass Timeout ]
      ...

    To add modifiers:
      LayoutTests/js/no-good.js
      [ Debug ] LayoutTests/js/no-good.js [ Pass Timeout ]
      [ Debug ] LayoutTests/js/no-good.js [ Pass Skip Timeout ]
      [ Linux Debug ] LayoutTests/js/no-good.js [ Pass Skip Timeout ]
      [ Linux Win ] LayoutTests/js/no-good.js [ Pass Skip Timeout ]

    Skip: Doesn't run the test.
    Slow: The test takes a long time to run, but does not timeout indefinitely.
    WontFix: For tests that we never intend to pass on a given platform (treated like Skip).

    Notes:
      -A test cannot be both SLOW and TIMEOUT
      -A test can be included twice, but not via the same path.
      -If a test is included twice, then the more precise path wins.
      -CRASH tests cannot be WONTFIX
    """

    # FIXME: Update to new syntax once the old format is no longer supported.
    EXPECTATIONS = {'pass': PASS,
                    'audio': AUDIO,
                    'fail': FAIL,
                    'image': IMAGE,
                    'image+text': IMAGE_PLUS_TEXT,
                    'text': TEXT,
                    'timeout': TIMEOUT,
                    'crash': CRASH,
                    'missing': MISSING,
                    'leak': LEAK,
                    'skip': SKIP}

    # Singulars
    EXPECTATION_DESCRIPTION = {SKIP: 'skipped',
                                PASS: 'pass',
                                FAIL: 'failure',
                                IMAGE: 'image-only failure',
                                TEXT: 'text-only failure',
                                IMAGE_PLUS_TEXT: 'image and text failure',
                                AUDIO: 'audio failure',
                                CRASH: 'crash',
                                TIMEOUT: 'timeout',
                                MISSING: 'missing',
                                LEAK: 'leak'}

    # (aggregated by category, pass/fail/skip, type)
    EXPECTATION_DESCRIPTIONS = {SKIP: 'skipped',
                                PASS: 'passes',
                                FAIL: 'failures',
                                IMAGE: 'image-only failures',
                                TEXT: 'text-only failures',
                                IMAGE_PLUS_TEXT: 'image and text failures',
                                AUDIO: 'audio failures',
                                CRASH: 'crashes',
                                TIMEOUT: 'timeouts',
                                MISSING: 'missing results',
                                LEAK: 'leaks'}

    EXPECTATION_ORDER = (PASS, CRASH, TIMEOUT, MISSING, FAIL, IMAGE, LEAK, SKIP)

    BUILD_TYPES = ('debug', 'release')

    MODIFIERS = {TestExpectationParser.SKIP_MODIFIER: SKIP,
                 TestExpectationParser.WONTFIX_MODIFIER: WONTFIX,
                 TestExpectationParser.SLOW_MODIFIER: SLOW,
                 TestExpectationParser.DUMPJSCONSOLELOGINSTDERR_MODIFIER: DUMPJSCONSOLELOGINSTDERR,
                 TestExpectationParser.REBASELINE_MODIFIER: REBASELINE,
                 'none': NONE}

    TIMELINES = {TestExpectationParser.WONTFIX_MODIFIER: WONTFIX,
                 'now': NOW}

    RESULT_TYPES = {'skip': SKIP,
                    'pass': PASS,
                    'fail': FAIL,
                    'flaky': FLAKY}

    @classmethod
    def expectation_from_string(cls, string):
        assert(' ' not in string)  # This only handles one expectation at a time.
        return cls.EXPECTATIONS.get(string.lower())

    @staticmethod
    def result_was_expected(result, expected_results, test_needs_rebaselining, test_is_skipped):
        """Returns whether we got a result we were expecting.
        Args:
            result: actual result of a test execution
            expected_results: set of results listed in test_expectations
            test_needs_rebaselining: whether test was marked as REBASELINE
            test_is_skipped: whether test was marked as SKIP"""
        if result in expected_results:
            return True
        if result in (TEXT, IMAGE_PLUS_TEXT, AUDIO) and (FAIL in expected_results):
            return True
        if result == MISSING and test_needs_rebaselining:
            return True
        if result == SKIP and test_is_skipped:
            return True
        return False

    @staticmethod
    def remove_pixel_failures(expected_results):
        """Returns a copy of the expected results for a test, except that we
        drop any pixel failures and return the remaining expectations. For example,
        if we're not running pixel tests, then tests expected to fail as IMAGE
        will PASS."""
        expected_results = expected_results.copy()
        if IMAGE in expected_results:
            expected_results.remove(IMAGE)
            expected_results.add(PASS) # FIXME: does it always become a pass?
        return expected_results

    @staticmethod
    def remove_leak_failures(expected_results):
        """Returns a copy of the expected results for a test, except that we
        drop any leak failures and return the remaining expectations. For example,
        if we're not running with --world-leaks, then tests expected to fail as LEAK
        will PASS."""
        expected_results = expected_results.copy()
        if LEAK in expected_results:
            expected_results.remove(LEAK)
            if not expected_results:
                expected_results.add(PASS)
        return expected_results

    @staticmethod
    def has_pixel_failures(actual_results):
        return IMAGE in actual_results or FAIL in actual_results

    @staticmethod
    def suffixes_for_expectations(expectations):
        suffixes = set()
        if IMAGE in expectations:
            suffixes.add('png')
        if FAIL in expectations:
            suffixes.add('txt')
            suffixes.add('png')
            suffixes.add('wav')
        return set(suffixes)

    def __init__(self, port, tests=None, include_generic=True, include_overrides=True, expectations_to_lint=None, force_expectations_pass=False, device_type=None):
        self._full_test_list = tests
        self._test_config = port.test_configuration()
        self._is_lint_mode = expectations_to_lint is not None
        self._model = TestExpectationsModel(self._shorten_filename)
        self._parser = TestExpectationParser(port, tests, self._is_lint_mode, self._shorten_filename)
        self._port = port
        self._skipped_tests_warnings = []
        self._expectations = []
        self._force_expectations_pass = force_expectations_pass
        self._device_type = device_type
        self._include_generic = include_generic
        self._include_overrides = include_overrides
        self._expectations_to_lint = expectations_to_lint

    def readable_filename_and_line_number(self, line):
        if line.not_applicable_to_current_platform:
            return "(skipped for this platform)"
        if not line.filename:
            return ''
        if line.filename.startswith(self._port.path_from_webkit_base()):
            return '{}:{}'.format(self._port.host.filesystem.relpath(line.filename, self._port.path_from_webkit_base()), line.line_number)
        return '{}:{}'.format(line.filename, line.line_number)

    def parse_generic_expectations(self):
        if self._port.path_to_generic_test_expectations_file() in self._expectations_dict:
            if self._include_generic:
                expectations = self._parser.parse(list(self._expectations_dict.keys())[self._expectations_dict_index], list(self._expectations_dict.values())[self._expectations_dict_index])
                self._add_expectations(expectations)
                self._expectations += expectations
            self._expectations_dict_index += 1

    def parse_default_port_expectations(self):
        if len(self._expectations_dict) > self._expectations_dict_index:
            expectations = self._parser.parse(list(self._expectations_dict.keys())[self._expectations_dict_index], list(self._expectations_dict.values())[self._expectations_dict_index])
            self._add_expectations(expectations)
            self._expectations += expectations
            self._expectations_dict_index += 1

    def parse_override_expectations(self):
        while len(self._expectations_dict) > self._expectations_dict_index and self._include_overrides:
            expectations = self._parser.parse(list(self._expectations_dict.keys())[self._expectations_dict_index], list(self._expectations_dict.values())[self._expectations_dict_index])
            self._add_expectations(expectations)
            self._expectations += expectations
            self._expectations_dict_index += 1

    def parse_all_expectations(self):
        self._expectations_dict = self._expectations_to_lint or self._port.expectations_dict(device_type=self._device_type)
        self._expectations_dict_index = 0

        self._has_warnings = False

        self.parse_generic_expectations()
        self.parse_default_port_expectations()
        self.parse_override_expectations()

        # FIXME: move ignore_tests into port.skipped_layout_tests()
        self.add_skipped_tests(self._port.skipped_layout_tests(self._full_test_list, device_type=self._device_type).union(set(self._port.get_option('ignore_tests', []))))

        self._report_warnings()
        self._process_tests_without_expectations()

    # TODO(ojan): Allow for removing skipped tests when getting the list of
    # tests to run, but not when getting metrics.
    def model(self):
        return self._model

    def get_rebaselining_failures(self):
        return self._model.get_test_set(REBASELINE)

    def filtered_expectations_for_test(self, test, pixel_tests_are_enabled, world_leaks_are_enabled):
        expected_results = self._model.get_expectations_or_pass(test)
        if not pixel_tests_are_enabled:
            expected_results = self.remove_pixel_failures(expected_results)
        if not world_leaks_are_enabled:
            expected_results = self.remove_leak_failures(expected_results)

        return expected_results

    def matches_an_expected_result(self, test, result, expected_results):
        return self.result_was_expected(result,
                                   expected_results,
                                   self.is_rebaselining(test),
                                   self._model.has_modifier(test, SKIP))

    def is_rebaselining(self, test):
        return self._model.has_modifier(test, REBASELINE)

    def _shorten_filename(self, filename):
        if filename.startswith(self._port.path_from_webkit_base()):
            return self._port.host.filesystem.relpath(filename, self._port.path_from_webkit_base())
        return filename

    def _report_warnings(self):
        warnings = []
        for expectation in self._expectations:
            for warning in expectation.warnings:
                warning = TestExpectationWarning(
                    self._shorten_filename(expectation.filename), expectation.line_number,
                    expectation.original_string, warning, expectation.name if expectation.expectations else None)
                warning.related_files = expectation.related_files
                warnings.append(warning)

        if warnings:
            self._has_warnings = True
            if self._is_lint_mode:
                raise ParseError(warnings)
            _log.warning('--lint-test-files warnings:')
            for warning in warnings:
                _log.warning(warning)
            _log.warning('')

    def _process_tests_without_expectations(self):
        if self._full_test_list:
            for test in self._full_test_list:
                if not self._model.has_test(test):
                    self._model.add_expectation_line(TestExpectationLine.create_passing_expectation(test))

    def has_warnings(self):
        return self._has_warnings

    def remove_configuration_from_test(self, test, test_configuration):
        expectations_to_remove = []
        modified_expectations = []

        for expectation in self._expectations:
            if expectation.name != test or expectation.is_flaky() or not expectation.parsed_expectations:
                continue
            if not any([value in (FAIL, IMAGE) for value in expectation.parsed_expectations]):
                continue
            if test_configuration not in expectation.matching_configurations:
                continue

            expectation.matching_configurations.remove(test_configuration)
            if expectation.matching_configurations:
                modified_expectations.append(expectation)
            else:
                expectations_to_remove.append(expectation)

        for expectation in expectations_to_remove:
            self._expectations.remove(expectation)

        return self.list_to_string(self._expectations, self._parser._test_configuration_converter, modified_expectations)

    def remove_rebaselined_tests(self, except_these_tests, filename):
        """Returns a copy of the expectations in the file with the tests removed."""
        def without_rebaseline_modifier(expectation):
            return (expectation.filename == filename and
                    not (not expectation.is_invalid() and
                         expectation.name in except_these_tests and
                         'rebaseline' in expectation.parsed_modifiers))

        return self.list_to_string(filter(without_rebaseline_modifier, self._expectations), reconstitute_only_these=[])

    def _add_expectations(self, expectation_list):
        for expectation_line in expectation_list:
            if self._force_expectations_pass:
                expectation_line.expectations = ['PASS']
                expectation_line.parsed_expectations = set([PASS])

            elif not expectation_line.expectations:
                continue

            if self._is_lint_mode or self._test_config in expectation_line.matching_configurations:
                self._model.add_expectation_line(expectation_line)

    def add_skipped_tests(self, tests_to_skip):
        if not tests_to_skip:
            return
        for test in self._expectations:
            if test.name and test.name in tests_to_skip:
                test.warnings.append('%s:%d %s is also in a Skipped file.' % (test.filename, test.line_number, test.name))

        for test_name in tests_to_skip:
            expectation_line = self._parser.expectation_for_skipped_test(test_name)
            self._model.add_expectation_line(expectation_line, in_skipped=True)

    @staticmethod
    def list_to_string(expectation_lines, test_configuration_converter=None, reconstitute_only_these=None):
        def serialize(expectation_line):
            # If reconstitute_only_these is an empty list, we want to return original_string.
            # So we need to compare reconstitute_only_these to None, not just check if it's falsey.
            if reconstitute_only_these is None or expectation_line in reconstitute_only_these:
                return expectation_line.to_string(test_configuration_converter)
            return expectation_line.original_string

        def nones_out(expectation_line):
            return expectation_line is not None

        return "\n".join(filter(nones_out, map(serialize, expectation_lines)))
