#  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
#  This source code is licensed under both the GPLv2 (found in the
#  COPYING file in the root directory) and Apache 2.0 License
#  (found in the LICENSE.Apache file in the root directory).

'''Filter for error messages in test output:
    - Receives merged stdout/stderr from test on stdin
    - Finds patterns of known error messages for test name (first argument)
    - Prints those error messages to stdout
'''

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import re
import sys


class ErrorParserBase(object):
    def parse_error(self, line):
        '''Parses a line of test output. If it contains an error, returns a
        formatted message describing the error; otherwise, returns None.
        Subclasses must override this method.
        '''
        raise NotImplementedError


class GTestErrorParser(ErrorParserBase):
    '''A parser that remembers the last test that began running so it can print
    that test's name upon detecting failure.
    '''
    _GTEST_NAME_PATTERN = re.compile(r'\[ RUN      \] (\S+)$')
    # format: '<filename or "unknown file">:<line #>: Failure'
    _GTEST_FAIL_PATTERN = re.compile(r'(unknown file|\S+:\d+): Failure$')

    def __init__(self):
        self._last_gtest_name = 'Unknown test'

    def parse_error(self, line):
        gtest_name_match = self._GTEST_NAME_PATTERN.match(line)
        if gtest_name_match:
            self._last_gtest_name = gtest_name_match.group(1)
            return None
        gtest_fail_match = self._GTEST_FAIL_PATTERN.match(line)
        if gtest_fail_match:
            return '%s failed: %s' % (
                    self._last_gtest_name, gtest_fail_match.group(1))
        return None


class MatchErrorParser(ErrorParserBase):
    '''A simple parser that returns the whole line if it matches the pattern.
    '''
    def __init__(self, pattern):
        self._pattern = re.compile(pattern)

    def parse_error(self, line):
        if self._pattern.match(line):
            return line
        return None


class CompilerErrorParser(MatchErrorParser):
    def __init__(self):
        # format: '<filename>:<line #>:<column #>: error: <error msg>'
        super(CompilerErrorParser, self).__init__(r'\S+:\d+:\d+: error:')


class ScanBuildErrorParser(MatchErrorParser):
    def __init__(self):
        super(ScanBuildErrorParser, self).__init__(
                r'scan-build: \d+ bugs found.$')


class DbCrashErrorParser(MatchErrorParser):
    def __init__(self):
        super(DbCrashErrorParser, self).__init__(r'\*\*\*.*\^$|TEST FAILED.')


class WriteStressErrorParser(MatchErrorParser):
    def __init__(self):
        super(WriteStressErrorParser, self).__init__(
                r'ERROR: write_stress died with exitcode=\d+')


class AsanErrorParser(MatchErrorParser):
    def __init__(self):
        super(AsanErrorParser, self).__init__(
                r'==\d+==ERROR: AddressSanitizer:')


class UbsanErrorParser(MatchErrorParser):
    def __init__(self):
        # format: '<filename>:<line #>:<column #>: runtime error: <error msg>'
        super(UbsanErrorParser, self).__init__(r'\S+:\d+:\d+: runtime error:')


class ValgrindErrorParser(MatchErrorParser):
    def __init__(self):
        # just grab the summary, valgrind doesn't clearly distinguish errors
        # from other log messages.
        super(ValgrindErrorParser, self).__init__(r'==\d+== ERROR SUMMARY:')


class CompatErrorParser(MatchErrorParser):
    def __init__(self):
        super(CompatErrorParser, self).__init__(r'==== .*[Ee]rror.* ====$')


class TsanErrorParser(MatchErrorParser):
    def __init__(self):
        super(TsanErrorParser, self).__init__(r'WARNING: ThreadSanitizer:')


_TEST_NAME_TO_PARSERS = {
    'punit': [CompilerErrorParser, GTestErrorParser],
    'unit': [CompilerErrorParser, GTestErrorParser],
    'release': [CompilerErrorParser, GTestErrorParser],
    'unit_481': [CompilerErrorParser, GTestErrorParser],
    'release_481': [CompilerErrorParser, GTestErrorParser],
    'clang_unit': [CompilerErrorParser, GTestErrorParser],
    'clang_release': [CompilerErrorParser, GTestErrorParser],
    'clang_analyze': [CompilerErrorParser, ScanBuildErrorParser],
    'code_cov': [CompilerErrorParser, GTestErrorParser],
    'unity': [CompilerErrorParser, GTestErrorParser],
    'lite': [CompilerErrorParser],
    'lite_test': [CompilerErrorParser, GTestErrorParser],
    'stress_crash': [CompilerErrorParser, DbCrashErrorParser],
    'write_stress': [CompilerErrorParser, WriteStressErrorParser],
    'asan': [CompilerErrorParser, GTestErrorParser, AsanErrorParser],
    'asan_crash': [CompilerErrorParser, AsanErrorParser, DbCrashErrorParser],
    'ubsan': [CompilerErrorParser, GTestErrorParser, UbsanErrorParser],
    'ubsan_crash': [CompilerErrorParser, UbsanErrorParser, DbCrashErrorParser],
    'valgrind': [CompilerErrorParser, GTestErrorParser, ValgrindErrorParser],
    'tsan': [CompilerErrorParser, GTestErrorParser, TsanErrorParser],
    'format_compatible': [CompilerErrorParser, CompatErrorParser],
    'run_format_compatible': [CompilerErrorParser, CompatErrorParser],
    'no_compression': [CompilerErrorParser, GTestErrorParser],
    'run_no_compression': [CompilerErrorParser, GTestErrorParser],
    'regression': [CompilerErrorParser],
    'run_regression': [CompilerErrorParser],
}


def main():
    if len(sys.argv) != 2:
        return 'Usage: %s <test name>' % sys.argv[0]
    test_name = sys.argv[1]
    if test_name not in _TEST_NAME_TO_PARSERS:
        return 'Unknown test name: %s' % test_name

    error_parsers = []
    for parser_cls in _TEST_NAME_TO_PARSERS[test_name]:
        error_parsers.append(parser_cls())

    for line in sys.stdin:
        line = line.strip()
        for error_parser in error_parsers:
            error_msg = error_parser.parse_error(line)
            if error_msg is not None:
                print(error_msg)


if __name__ == '__main__':
    sys.exit(main())
