#!/usr/bin/env python3
# Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

# Compare multiple CTS test_result.xml files

from __future__ import print_function
from os.path import basename
import argparse
import os
import sys

import utils


class Module:

    def __init__(self):
        self.test_cases = {}
        self.bf_covered_in_file = 0  # bitfield, one bit per file

    def get_test_case_maybe_create(self, test_case_name):
        return self.test_cases.setdefault(test_case_name, TestCase())

    def set_file_index_present(self, file_idx):
        self.bf_covered_in_file |= (1 << file_idx)

    def report(self, module_name, files, diff_only):
        bf_all_files = self.bf_covered_in_file
        for test_case_name, test_case in self.test_cases.iteritems():
            if test_case.bf_covered_in_file != bf_all_files:
                report_missing_thing('test_case',
                                     module_name + '/' + test_case_name,
                                     test_case.bf_covered_in_file, files)
        for test_case_name, test_case in self.test_cases.iteritems():
            test_case.report(module_name, test_case_name, files, diff_only)


class TestCase:

    def __init__(self):
        self.tests = {}
        self.bf_covered_in_file = 0  # bitfield, one bit per file

    def get_test_maybe_create(self, test_name):
        return self.tests.setdefault(test_name, Test())

    def set_file_index_present(self, file_idx):
        self.bf_covered_in_file |= (1 << file_idx)

    def report(self, module_name, test_case_name, files, diff_only):
        bf_all_files = self.bf_covered_in_file
        for test_name, test in self.tests.iteritems():
            do_report = test.bf_passing_in_file != bf_all_files
            if diff_only:
                do_report = do_report and test.bf_failing_in_file != bf_all_files
            if do_report:
                test.report(module_name, test_case_name, test_name, files)


class Test:

    def __init__(self):
        self.bf_failing_in_file = 0  # bitfields, one bit per file
        self.bf_passing_in_file = 0

    def set_file_index_outcome(self, outcome_is_passed, file_idx):
        bf_value = (1 << file_idx)
        if outcome_is_passed:
            self.bf_passing_in_file |= bf_value
        else:
            self.bf_failing_in_file |= bf_value

    # Report test's status in all files: pass/fail/missing
    def report(self, module_name, test_case_name, test_name, files):
        print('Test: {}/{}/{}:'.format(module_name, test_case_name, test_name))
        for file_idx, f in enumerate(files):
            bf_value = 1 << file_idx
            print('\t- {:20}'.format(basename(f)), end='')
            if self.bf_passing_in_file & bf_value:
                print('PASS')
            elif self.bf_failing_in_file & bf_value:
                print('     FAIL')
            else:
                print(' --   --  (missing)')


def parse_arguments():
    parser = argparse.ArgumentParser(
        description='Compare multiple Android CTS test_result.xml files.')
    parser.add_argument('files',
                        nargs='+',
                        help='List of (possibly renamed) test_result.xml files')
    parser.add_argument(
        '--diff-only',
        action='store_true',
        help="Don't list tests that consistently fail in all result files,"
        " list only differences.")
    return parser.parse_args()


# Read CTS test_result.xml from file and merge into result_tree
def add_to_result_tree(result_tree, file_xml, file_idx):
    module = None
    test_case = None
    for x in utils.read_cts_test_result(file_xml):
        if type(x) is utils.CtsModule:
            module = result_tree.setdefault(x.name, Module())
            module.set_file_index_present(file_idx)
        elif type(x) is utils.CtsTestCase:
            test_case = module.get_test_case_maybe_create(x.name)
            test_case.set_file_index_present(file_idx)
        else:
            assert (type(x) is utils.CtsTest)
            v = test_case.get_test_maybe_create(x.name)
            v.set_file_index_outcome(x.outcome, file_idx)


# main tree_report function
def tree_report(result_tree, files, diff_only):
    bf_all_files = (1 << len(files)) - 1
    for module_name, module in result_tree.iteritems():
        if module.bf_covered_in_file != bf_all_files:
            report_missing_thing('module', module_name,
                                 module.bf_covered_in_file, files)
    for module_name, module in result_tree.iteritems():
        module.report(module_name, files, diff_only)


def report_missing_thing(thing_type, thing_name, bf_covered_in_file, files):
    print('Missing {}: {}, from:'.format(thing_type, thing_name))
    for file_idx, f in enumerate(files):
        if not (bf_covered_in_file & (1 << file_idx)):
            print('\t- ' + f)


def Main():
    m = Module()
    m.get_test_case_maybe_create('qwe')

    args = parse_arguments()

    result_tree = {}
    for file_idx, f in enumerate(args.files):
        add_to_result_tree(result_tree, f, file_idx)

    tree_report(result_tree, args.files, args.diff_only)

    return 0


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