#!/usr/bin/env python
"""
    An LTP [execution and] parsing wrapper.

    Used as a second layer for ease-of-use with users as many developers
    complain about complexity involved with trying to use LTP in my
    organization -_-.

    Copyright (C) 2009-2012, Garrett Cooper

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""


from optparse import OptionGroup, OptionParser
import os
import re
import sys


class ResultsParseException(Exception):
    """ Extended class for parsing LTP results. """


def parse_ltp_results(exec_log, output_log, verbose=0):
    """Function for parsing LTP results.

    1. The exec log is the log with the results in summary form.

    And now a note from our sponsors about exec logs...

    startup='Thu Oct  1 06:42:07 2009'
    tag=abort01 stime=1254379327 dur=2 exit=exited stat=0 core=no cu=0 cs=16
    tag=accept01 stime=1254379329 dur=0 exit=exited stat=0 core=no cu=1 cs=0
    tag=access01 stime=1254379329 dur=0 exit=exited stat=0 core=no cu=0 cs=0
    tag=access02 stime=1254379329 dur=0 exit=exited stat=0 core=no cu=0 cs=0
    tag=access03 stime=1254379329 dur=1 exit=exited stat=0 core=no cu=0 cs=1

    [...]

    a. tag is the test tag name.
    b. stime is the system time at the start of the exec.
    c. dur is the total duration of the test.
    d. exit tells you what the result was. Valid values are:
       - exited
       - signaled
       - stopped
       - unknown
       See run_child in pan.c.
    e. stat is the exit status.
    f. core answers the question: `did I dump core?'.
    g. cu is the cutime (cumulative user time).
    h. cs is the cstime (cumulative system time).

    2. The output log is the log with all of the terse results.
    3. verbose tells us whether or not we need to include the passed results.
    """

    if not os.access(exec_log, os.R_OK):
        raise ResultsParseException("Exec log - %s - specified doesn't exist"
                                    % exec_log)
    elif 1 < verbose and not os.access(output_log, os.R_OK):
        # Need the output log for context to the end user.
        raise ResultsParseException("Output log - %s - specified doesn't exist"
                                    % output_log)

    context = None

    failed = []
    passed = 0

    if 2 <= verbose:
        passed = []

    target_vals = ('exited', '0', 'no')

    fd = open(exec_log, 'r')

    try:
        content = fd.read()
        matches = re.finditer('tag=(?P<tag>\w+).+exit=(?P<exit>\w+) '
                              'stat=(?P<stat>\d+) core=(?P<core>\w+)', content)
    finally:
        content = None
        fd.close()

    if not matches:
        raise ResultsParseException("No parseable results were found in the "
                                    "exec log - `%s'." % exec_log)

    for match in matches:

        if ((match.group('exit'), match.group('stat'), match.group('core')) !=
             target_vals):
            failed.append(match.group('tag'))
        elif 2 <= verbose:
            passed.append(match.group('tag'))
        else:
            passed += 1

    # Save memory on large files because lists can eat up a fair amount of
    # memory.
    matches = None

    if 1 <= verbose:

        context = {}

        search_tags = failed[:]

        if 2 <= verbose:
            search_tags += passed

        search_tags.sort()

        fd = open(output_log, 'r')

        try:

            line_iterator = getattr(fd, 'xreadlines', getattr(fd, 'readlines'))

            end_output = '<<<execution_status>>>'
            output_start = '<<<test_output>>>'

            tag_re = re.compile('tag=(\w+)')

            grab_output = False

            local_context = ''

            search_tag = None

            try:

                while True:

                    line = line_iterator.next()

                    if line.startswith(end_output):

                        if search_tag:
                            context[search_tag] = local_context

                        grab_output = False
                        local_context = ''
                        search_tag = None

                    if not search_tag:

                        while True:

                            line = line_iterator.next()

                            match = tag_re.match(line)

                            if match and match.group(1) in search_tags:
                                search_tag = match.group(1)
                                break

                    elif line.startswith(output_start):
                        grab_output = True
                    elif grab_output:
                        local_context += line

            except StopIteration:
                pass

            for k in context.keys():
                if k not in search_tags:
                    raise ResultsParseException('Leftover token in search '
                                                'keys: %s' % k)

        except Exception as exc:
            # XXX (garrcoop): change from Exception to soft error and print
            # out warning with logging module.
            raise ResultsParseException('Encountered exception reading output '
                                        'for context: %s' % str(exc))
        finally:
            fd.close()

    return failed, passed, context


def determine_context(output_log, testsuite, test_set, context):
    """Return a set of context values mapping test_set -> context."""

    test_set_context = {}

    for test in test_set:

        if test in context:
            test_context = context[test]
            del context[test]
        else:
            test_context = ('Could not determine context for %s; please see '
                            'output log - %s' % (test, output_log))

        test_set_context['%s : %s' % (testsuite, test)] = test_context

    return test_set_context


def print_context(output_dest, header, testsuite_context):
    """Print out testsuite_context to output_dest, heading it up with
       header.
    """

    output_dest.write('\n'.join(['', '=' * 40, header, '-' * 40, '']))

    for test, context in testsuite_context.items():
        output_dest.write('<output test="%s">\n%s\n</output>\n' %
                          (test, context.strip()))


def main():
    """main"""

    parser = OptionParser(prog=os.path.basename(sys.argv[0]),
                          usage='usage: %prog [options] test ...',
                          version='0.0.2')

    ltpdir = os.getenv('LTPROOT', '@prefix@')

    parser.add_option('-l', '--ltp-dir', dest='ltp_dir',
                      default=ltpdir, help='LTP directory [default: %default]')
    parser.add_option('-L', '--log-dir', dest='log_dir',
                      default=None,
                      help=('directory for [storing and] retrieving logs '
                            '[default: %s/output]' % ltpdir),
                      metavar='DIR')
    parser.add_option('-p', '--postprocess-only', dest='postprocess_only',
                      default=False, action='store_true',
                      help=("Don't execute runltp; just postprocess logs "
                            "[default: %default]."))
    parser.add_option('-o', '--output-file', dest='output_file',
                      default=None,
                      help='File to output results')
    parser.add_option('-r', '--runltp-opts', dest='runltp_opts',
                      default='',
                      help=('options to pass directly to runltp (will '
                            'suppress -q).'))

    group = OptionGroup(parser, 'Logging',
                        'If --summary-mode is 0, then the summary output is '
                        'suppressed. '
                        'If --summary-mode is 1 [the default], then summary '
                        'output will be displayed for test execution'
                        'If --summary-mode is 2, then summary output will be '
                        'provided on a per-test suite basis. If only '
                        'one test suite is specified, this has the same net '
                        "effect as `--summary-mode 1'"
                        'If --verbose is specified once, prints out failed '
                        'test information with additional context. '
                        'If --verbose is specified twice, prints out the '
                        'failed and passed test context, as well as the '
                        'summary.')

    parser.add_option('-s', '--summary-mode', dest='summary_mode', default=1,
                      type='int',
                      help='See Logging.')

    parser.add_option('-v', '--verbose', dest='verbose', default=0,
                      action='count',
                      help=('Increases context verbosity from tests. See '
                            'Verbosity for more details.'))
    parser.add_option_group(group)

    group = OptionGroup(parser, 'Copyright',
                        '%(prog)s version %(version)s, Copyright (C) '
                        '2009-2012, Garrett Cooper %(prog)s comes with '
                        'ABSOLUTELY NO WARRANTY; '
                        'This is free software, and you are welcome to '
                        'redistribute it under certain conditions (See the '
                        'license tort in %(file)s for more details).'
                        % { 'file'    : os.path.abspath(__file__),
                            'prog'    : parser.prog,
                            'version' : parser.version })

    parser.add_option_group(group)

    opts, args = parser.parse_args()

    # Remove -q from the opts string, as long as it's a standalone option.
    runltp_opts = re.sub('^((?<!\S)+\-q\s+|\-q|\s+\-q(?!\S))$', '',
                         opts.runltp_opts)

    if not opts.log_dir:
        opts.log_dir = os.path.join(opts.ltp_dir, 'output')

    if not opts.summary_mode and not opts.verbose:
        parser.error('You cannot suppress summary output and disable '
                     'verbosity.')
    elif opts.summary_mode not in range(3):
        parser.error('--summary-mode must be a value between 0 and 2.')

    if len(args) == 0:
        # Default to scenarios also used by runltp.
        fd = open(os.path.join(ltpdir, 'scenario-groups/default'), 'r')
        try:
            args = fd.readlines()
        finally:
            fd.close()

    if opts.output_file:

        output_dir = os.path.dirname(opts.output_file)

        if output_dir:
            # Not cwd; let's check to make sure that the directory does or
            # does not exist.

            if not os.path.exists(output_dir):
                # We need to make the directory.
                os.makedirs(os.path.dirname(opts.output_file))
            elif not os.path.isdir(os.path.abspath(output_dir)):
                # Path exists, but isn't a file. Oops!
                parser.error('Dirname for path specified - %s - is not valid'
                             % output_dir)

        else:
            # Current path (cwd)
            opts.output_file = os.path.join(os.getcwd(), opts.output_file)

        output_dest = open(opts.output_file, 'w')

    else:

        output_dest = sys.stdout

    try:

        failed_context = {}
        passed_context = {}

        failed_count = 0
        passed_count = 0

        if opts.summary_mode == 2 and len(args) == 1:
            opts.summary_mode = 1

        for testsuite in args:

            # Iterate over the provided test list

            context = {}
            exec_log = os.path.join(opts.log_dir, '%s-exec.log' % testsuite)
            output_log = os.path.join(opts.log_dir, ('%s-output.log'
                                                     % testsuite))

            failed_subset = {}

            runtest_file = os.path.join(opts.ltp_dir, 'runtest', testsuite)

            if not opts.postprocess_only:

                for log in [exec_log, output_log]:
                    if os.path.isfile(log):
                        os.remove(log)

                if not os.access(runtest_file, os.R_OK):
                    output_dest.write("%s doesn't exist; skipping "
                                      "test\n" % runtest_file)
                    continue

                os.system(' '.join([os.path.join(opts.ltp_dir, 'runltp'),
                                    runltp_opts, '-f', testsuite,
                                    '-l', exec_log, '-o', output_log]))

            try:

                failed_subset, passed_css, context = \
                    parse_ltp_results(exec_log, output_log,
                                  verbose=opts.verbose)

            except ResultsParseException as rpe:
                output_dest.write('Error encountered when parsing results for '
                                  'test - %s: %s\n' % (testsuite, str(rpe)))
                continue

            failed_count += len(failed_subset)

            failed_subset_context = {}
            passed_subset_context = {}

            if opts.verbose:
                failed_subset_context = determine_context(output_log,
                                                          testsuite,
                                                          failed_subset,
                                                          context)
            if type(passed_css) == list:

                passed_count += len(passed_css)

                if opts.verbose == 2:
                    passed_subset_context = determine_context(output_log,
                                                              testsuite,
                                                              passed_css,
                                                              context)

            else:

                passed_count += passed_css

            if opts.summary_mode == 1:

                failed_context.update(failed_subset_context)
                passed_context.update(passed_subset_context)

            else:

                if 1 <= opts.verbose:
                    # Print out failed testcases.
                    print_context(output_dest,
                                  'FAILED TESTCASES for %s' % testsuite,
                                  failed_subset_context)

                if opts.verbose == 2:
                    # Print out passed testcases with context.
                    print_context(output_dest,
                                  'PASSED TESTCASES for %s' % testsuite,
                                  passed_subset_context)

                if opts.summary_mode == 2:
                    output_dest.write("""
========================================
SUMMARY for: %s
----------------------------------------
PASS - %d
FAIL - %d
----------------------------------------
""" % (testsuite, passed_count, len(failed_subset)))

        if opts.summary_mode == 1:

            # Print out overall results.

            if 1 <= opts.verbose:
                # Print out failed testcases with context.
                print_context(output_dest, "FAILED TESTCASES", failed_context)

            if opts.verbose == 2:
                # Print out passed testcases with context.
                print_context(output_dest, "PASSED TESTCASES", passed_context)

            output_dest.write("""
========================================
SUMMARY for tests:
%s
----------------------------------------
PASS - %d
FAIL - %d
----------------------------------------
""" % (' '.join(args), passed_count, failed_count))

    finally:

        if output_dest != sys.stdout:

            output_dest.close()

if __name__ == '__main__':
    main()
