#!/usr/bin/python
#
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""This module calculates the test summary of specified test result files."""


import getopt
import glob
import operator
import os
import re
import sys
import time

import common_util
import trackpad_util

from trackpad_util import read_trackpad_test_conf, KEY_LOG, KEY_SEQ


# Define some constants and formats for parsing the result file
RESULT_END = 'End of Test Summary'
RESULT_STOP = 'stop'
RESULT_NOT_FUNCTIONALITY = 'not functionality'
RESULT_FORMAT_PASS_RATE = '      {0:<50}: {1:4s}  {2:9s} passed'
RESULT_PATTERN_PASS_RATE = \
        u'\s*(\S+)\s*:\s*\d+%\s*\s\(\s*(\d+)\D+(\d+)\s*\)\s*passed'
SUMMARY_LABEL = '_tut1_'
LINE_SPLIT = '\n'


def format_result_header(file_name, tot_pass_count, tot_count):
    """Format the result header."""
    header = []
    header.append(LINE_SPLIT)
    header.append('Result summary file: %s' % file_name)
    ratio = 0 if tot_count == 0 else (1.0 * tot_pass_count / tot_count)
    tot_pass_rate_str = '%3.0f%%' % (100.0 * ratio)
    header.append('*** Total pass rate: %s' % tot_pass_rate_str)
    msg = ('*** Total number of (passed / tested) files: (%d / %d)\n\n' %
           (tot_pass_count, tot_count))
    header.append(msg)
    return LINE_SPLIT.join(header)


def format_result_area(area_name):
    """Format of the area name."""
    return '  Area: %s' % area_name


def format_result_pass_rate(name, pass_count, test_count):
    """Format the line of the pass rate and pass count."""
    pass_rate_str = '%3.0f%%' % (100.0 * pass_count / test_count)
    count_str = '(%2d / %2d)' % (pass_count, test_count)
    return RESULT_FORMAT_PASS_RATE.format(name, pass_rate_str, count_str)


def format_result_body(summary_list, pass_count, tot_count, gss_vlog_dict,
                       flag_vlog=False):
    """Format the body of the test result."""
    body = []
    area = None
    for s in summary_list:
        if s.lstrip().startswith('Area'):
            body.append(s)
            # Extract area name
            #   e.g., "Area: click"
            area = s.split(':')[1].strip()
        else:
            if pass_count.has_key(s) and tot_count.has_key(s):
                line = format_result_pass_rate(s, pass_count[s], tot_count[s])
            else:
                line = '%s: %s' % (s, 'Warning: missing counts')
            if flag_vlog:
                line = LINE_SPLIT + line
            body.append(line)

            if flag_vlog:
                if area is not None:
                    # E.g.,
                    # area: click
                    # s: no_cursor_wobble.tap
                    # fullname: click-no_cursor_wobble.tap
                    fullname = '-'.join([area, s])
                    for filename, root_cause in \
                            gss_vlog_dict[KEY_LOG][fullname]:
                        line = '          %s:' % os.path.basename(filename)
                        body.append(line)
                        for c in root_cause:
                            rc = root_cause[c]
                            if isinstance(rc, list):
                                indent = '                  %s'
                                indent_rc = list(indent % str(i) for i in rc)
                                rc = LINE_SPLIT.join(indent_rc)
                                line = '              %s:\n%s' % (c, rc)
                            else:
                                line = '              %s: %s' % (c, rc)
                            body.append(line)

    return LINE_SPLIT.join(body)


def format_result_tail():
    """Format the tail of the result."""
    return '\n\n*** %s\n\n' % RESULT_END


def get_count_from_result_line(line):
    """Get the pass count and total count from a given line."""
    if RESULT_END in line:
        return RESULT_STOP

    # Try to extract information from a result line which looks as
    # '      no_cursor_wobble.tap             :   50%  ( 1 / 2 )  passed'
    m = re.search(RESULT_PATTERN_PASS_RATE, line)
    if m is None:
        return RESULT_NOT_FUNCTIONALITY

    fullname = m.group(1)
    single_pass_count = int(m.group(2))
    single_tot_count = int(m.group(3))
    return (fullname, single_pass_count, single_tot_count)


def insert_list(summary_list, fullname, area):
    """Insert a functionality fullname to the end of a given area."""
    if area is not None:
        summary_list_length = len(summary_list)
        if summary_list_length == 0:
            return False

        found_the_area = False
        index = None
        for i, s in enumerate(summary_list):
            if found_the_area:
                flag_found_next_area = re.search('Area:', s, re.I) is not None
                if flag_found_next_area:
                    index = i
                    break
            elif re.search('Area\s*:\s*%s' % area, s, re.I) is not None:
                found_the_area = True

        flag_end_of_list = (i == summary_list_length - 1)
        if index is None and found_the_area and flag_end_of_list:
            index = summary_list_length

        if index is not None:
            summary_list.insert(index, fullname)
            return True

    return False


class TrackpadResult:
    """Calculate integrated results over a number of gesture sets."""

    def __init__(self, results_dir=None):
        if results_dir is None:
            result_name = 'gesture_files_path_results'
            results_dir = read_trackpad_test_conf(result_name, '.')

        self.results_dir = results_dir
        if not os.path.isdir(self.results_dir):
            os.makedirs(self.results_dir)
            print '"%s" is created.\n' % self.results_dir

        self._open_summary_file()
        print 'The summary file is saved in %s.\n' % self.summary_name

        msg = ('A report of trackpad autotest analysis on trackpad '
               'usability study\n')
        self.summary_file.write(msg)
        msg = '     Gesture Sets Results Directory: "%s"\n' % self.results_dir
        self.summary_file.write(msg)
        self._get_results_files()

    def _get_results_files(self):
        """Collect results_files from results_dir."""
        self.label = SUMMARY_LABEL
        _results = glob.glob(os.path.join(self.results_dir, '*'))
        self.results_files = filter(lambda f: self.label in f and
                                              os.path.isfile(f), _results)

    def _open_summary_file(self):
        time_format = '%Y%m%d_%H%M%S'
        summary_time = 'summary:' + time.strftime(time_format, time.gmtime())
        self.summary_name = os.path.join(self.results_dir, summary_time)
        self.summary_file = open(self.summary_name, 'w')

    def calc_test_summary(self, gss_vlog_dict, flag_vlog=False):
        """Calculate the test summary of test result files in the result_dir."""
        # Initialization
        pass_count = {}
        tot_count = {}
        fullname_list = []
        summary_list = []

        if not self.results_files:
            print 'Warning: no result files in "%s".' % self.results_dir
            return False

        if flag_vlog:
            msg = '\n\n\nThe detailed root causes of failed cases:\n'
            self.summary_file.write(msg)
            self.summary_file.write('-' *  len(msg.strip('\n')))

        for rfile in self.results_files:
            with open(rfile) as f:
                area = None
                for line in f:
                    rv = get_count_from_result_line(line)
                    if rv == RESULT_NOT_FUNCTIONALITY:
                        # An area looks as
                        # '  Area: click '
                        m = re.search('\s*Area:\s*(\S+)\s*', line, re.I)
                        if m is not None:
                            area = m.group(1)
                            area_line = format_result_area(area)
                            if flag_vlog:
                                area_line = '\n' + area_line
                            if area_line not in summary_list:
                                summary_list.append(area_line)
                        continue
                    elif rv == RESULT_STOP:
                        break
                    else:
                        fullname, single_pass_count, single_tot_count = rv
                        if fullname not in pass_count:
                            pass_count[fullname] = 0
                            tot_count[fullname] = 0
                        pass_count[fullname] += single_pass_count
                        tot_count[fullname] += single_tot_count
                        if fullname not in summary_list:
                            # Insert the functionality fullname in the area
                            if not insert_list(summary_list, fullname, area):
                                msg = '  Warning: cannot insert %s into area %s'
                                print (msg % (fullname, area))

        # Calculate the final statistics
        if pass_count.values():
            final_pass_count = reduce(operator.add, pass_count.values())
        else:
            final_pass_count = 0
        if tot_count.values():
            final_tot_count = reduce(operator.add, tot_count.values())
        else:
            final_tot_count = 0

        # Create a test result summary
        header = format_result_header(self.summary_name, final_pass_count,
                                      final_tot_count)
        body = format_result_body(summary_list, pass_count, tot_count,
                                  gss_vlog_dict, flag_vlog=flag_vlog)
        tail = format_result_tail()

        self.summary_file.write(header)
        self.summary_file.write(body)
        self.summary_file.write(tail)

        return True

    def get_vlog(self, vlog_file):
        ''' Extract verification log from the vlog_file

        The files contains something like
            vlog{attr}={'log': {...}, 'seq': {...}}
        '''
        vlog_dict = None
        with open(vlog_file) as f:
            for line in f:
                if line.startswith('Verification Log'):
                    vlog_dict = eval(line.split('=', 1)[1])
                    break
        return vlog_dict

    def _result_exists(self, gesture_set):
        ''' Check if a result file of a gesture set (gs) already exists'''
        gs = os.path.basename(gesture_set)
        gs_in_results = filter(lambda result_file: gs in result_file,
                               self.results_files)
        return len(gs_in_results) > 0

    def hardware_trackpad_test_all(self, gss_path=None, allow_duplicate=False):
        ''' Run all trackpad autotest analysis on all gesture sets (gss)

        When allow_duplicate is True, it means to run autotest analysis for
        the gesture sets no matter whether the result files of the gesture
        sets exist or not.
        '''
        if gss_path is None:
            gss_path = read_trackpad_test_conf('gesture_files_path_root', '.')

        if not os.path.isdir(gss_path):
            print 'Error: "%s" does not exist.' % gss_path
            sys.exit(1)
        print '     Gesture Sets: "%s"' % gss_path

        autotest_link = read_trackpad_test_conf('gesture_files_path_autotest',
                                                '.')
        autotest_program = read_trackpad_test_conf('autotest_program', '.')

        for gs in glob.glob(os.path.join(gss_path, '*')):
            if (self.label in gs and
                (allow_duplicate or not self._result_exists(gs))):
                if os.path.islink(gs):
                    continue
                if os.path.isfile(gs):
                    continue
                print '  Test the gesture set "%s"' % gs
                if os.path.islink(autotest_link):
                    os.remove(autotest_link)
                os.symlink(gs, autotest_link)
                cmd = '%s %s' % (autotest_program, 'control')
                common_util.simple_system(cmd)

        # Update the results_files since more results files have been created.
        self._get_results_files()

    def hardware_trackpad_vlog_all(self, results_dir=None, flag_vlog=False):
        ''' Collect all verification logs from all gesture set results path. '''

        if results_dir is None:
            results_dir = self.results_dir

        # Initialize a cross-iteration verification dictionary for all gss
        gss_vlog_dict = {}
        gss_vlog_dict[KEY_LOG] = {}
        gss_vlog_dict[KEY_SEQ] = []

        # Integrate all the verification log
        msg = '\nThis summary report is derived from the following %d users:\n'
        self.summary_file.write(msg % len(self.results_files))
        for result_file in self.results_files:
            vlog_dict = self.get_vlog(result_file)

            user_date = os.path.basename(result_file).split('.')[0]
            if SUMMARY_LABEL in user_date:
                user, date = user_date.split(SUMMARY_LABEL)
                msg = '     user: %s (%s)\n' % (user, date)
                self.summary_file.write(msg)

            if vlog_dict is not None:
                for gname in vlog_dict[KEY_SEQ]:
                    if gname not in gss_vlog_dict[KEY_SEQ]:
                        gss_vlog_dict[KEY_SEQ].append(gname)
                        gss_vlog_dict[KEY_LOG][gname] = []
                    if gname in vlog_dict[KEY_LOG]:
                        filename = vlog_dict[KEY_LOG][gname]['file']
                        root_cause = vlog_dict[KEY_LOG][gname]['root_cause']
                        gss_vlog_dict[KEY_LOG][gname].append([filename,
                                                            root_cause])

        # Print all the verification log
        if flag_vlog:
            print '\n\ngss_vlog_dict:'
            for gname in gss_vlog_dict[KEY_SEQ]:
                print '  %s:' % gname
                for filename, root_cause in gss_vlog_dict[KEY_LOG][gname]:
                    print '    %s:' % os.path.basename(filename)
                    for c in root_cause:
                        print '        %s: %s' % (c, root_cause[c])

        return gss_vlog_dict


def _usage():
    """Print the usage of this program."""
    # Print the usage
    print 'Usage: $ %s [options]\n' % sys.argv[0]
    print 'options:'
    print '  -d, --dir=<result_directory>'
    print '         <result_directory>: the path containing result files'
    print '  -e, --enforce: enforce to run autotest analysis. Default is False.'
    print '  -h, --help: show this help'
    print '  -t, --tar: To tar all tpcontrol log files.'
    print


def _parsing_error(msg):
    """Print the usage and exit when encountering parsing error."""
    print 'Error: %s' % msg
    _usage()
    sys.exit(1)


def _parse_options():
    """Parse the command line options."""
    try:
        short_opt = 'hd:et'
        long_opt = ['help', 'dir=', 'enforce', 'tar']
        opts, args = getopt.getopt(sys.argv[1:], short_opt, long_opt)
    except getopt.GetoptError, err:
        _parsing_error(str(err))

    # Initialize the option dictionary
    option_dict = {}
    option_dict['results_dir'] = read_trackpad_test_conf(
                                        'gesture_files_path_results', '.')
    option_dict['enforce'] = False
    option_dict['tar'] = False
    for opt, arg in opts:
        if opt in ('-h', '--help'):
            _usage()
            sys.exit(1)
        elif opt in ('-d', '--dir'):
            if os.path.isdir(arg):
                option_dict['results_dir'] = arg
            else:
                print 'Error: the result directory "%s" does not exist.' % arg
                sys.exit(1)
        elif opt in ('-e', '--enforce'):
            option_dict['enforce'] = True
        elif opt in ('-t', '--tar'):
            option_dict['tar'] = True
        else:
            msg = 'Error: This option %s is not handled in program' % opt
            _parsing_error(msg)

    return option_dict


def main():
    """Run trackpad autotest on all gesture sets and create a summary report."""
    # Parse command options
    option_dict = _parse_options()
    tresult = TrackpadResult(results_dir=option_dict['results_dir'])

    # Determine whether to execute autotest analysis on gesture sets
    if option_dict['enforce']:
        tresult.hardware_trackpad_test_all()

    # Tar all tpcontrol logs into a tar ball
    if option_dict['tar']:
        trackpad_util.TpcontrolLog().tar_tpcontrol_logs()

    # Collect verification logs from all analysis logs
    gss_vlog_dict = tresult.hardware_trackpad_vlog_all()

    # Calculate the test summary over the analysis log without detailed logs
    tresult.calc_test_summary(gss_vlog_dict, flag_vlog=False)

    # List the test summary over the analysis log with detailed root causes
    # of failed cases
    tresult.calc_test_summary(gss_vlog_dict, flag_vlog=True)


if __name__ == '__main__':
    main()
