#
# SPDX-License-Identifier: MIT
#

import sys
import os
import re

# A parser that can be used to identify weather a line is a test result or a section statement.
class PtestParser(object):
    def __init__(self):
        self.results = {}
        self.sections = {}

    def parse(self, logfile):
        test_regex = {}
        test_regex['PASSED'] = re.compile(r"^PASS:(.+)")
        test_regex['FAILED'] = re.compile(r"^FAIL:([^(]+)")
        test_regex['SKIPPED'] = re.compile(r"^SKIP:(.+)")

        section_regex = {}
        section_regex['begin'] = re.compile(r"^BEGIN: .*/(.+)/ptest")
        section_regex['end'] = re.compile(r"^END: .*/(.+)/ptest")
        section_regex['duration'] = re.compile(r"^DURATION: (.+)")
        section_regex['exitcode'] = re.compile(r"^ERROR: Exit status is (.+)")
        section_regex['timeout'] = re.compile(r"^TIMEOUT: .*/(.+)/ptest")

        # Cache markers so we don't take the re.search() hit all the time.
        markers = ("PASS:", "FAIL:", "SKIP:", "BEGIN:", "END:", "DURATION:", "ERROR: Exit", "TIMEOUT:")

        def newsection():
            return { 'name': "No-section", 'log': [] }

        current_section = newsection()

        with open(logfile, errors='replace') as f:
            for line in f:
                if not line.startswith(markers):
                    current_section['log'].append(line)
                    continue

                result = section_regex['begin'].search(line)
                if result:
                    current_section['name'] = result.group(1)
                    continue

                result = section_regex['end'].search(line)
                if result:
                    if current_section['name'] != result.group(1):
                        bb.warn("Ptest END log section mismatch %s vs. %s" % (current_section['name'], result.group(1)))
                    if current_section['name'] in self.sections:
                        bb.warn("Ptest duplicate section for %s" % (current_section['name']))
                    self.sections[current_section['name']] = current_section
                    del self.sections[current_section['name']]['name']
                    current_section = newsection()
                    continue

                result = section_regex['timeout'].search(line)
                if result:
                    if current_section['name'] != result.group(1):
                        bb.warn("Ptest TIMEOUT log section mismatch %s vs. %s" % (current_section['name'], result.group(1)))
                    current_section['timeout'] = True
                    continue

                for t in ['duration', 'exitcode']:
                    result = section_regex[t].search(line)
                    if result:
                        current_section[t] = result.group(1)
                        continue

                current_section['log'].append(line)

                for t in test_regex:
                    result = test_regex[t].search(line)
                    if result:
                        if current_section['name'] not in self.results:
                            self.results[current_section['name']] = {}
                        self.results[current_section['name']][result.group(1).strip()] = t

        # Python performance for repeatedly joining long strings is poor, do it all at once at the end.
        # For 2.1 million lines in a log this reduces 18 hours to 12s.
        for section in self.sections:
            self.sections[section]['log'] = "".join(self.sections[section]['log'])

        return self.results, self.sections

    # Log the results as files. The file name is the section name and the contents are the tests in that section.
    def results_as_files(self, target_dir):
        if not os.path.exists(target_dir):
            raise Exception("Target directory does not exist: %s" % target_dir)

        for section in self.results:
            prefix = 'No-section'
            if section:
                prefix = section
            section_file = os.path.join(target_dir, prefix)
            # purge the file contents if it exists
            with open(section_file, 'w') as f:
                for test_name in sorted(self.results[section]):
                    status = self.results[section][test_name]
                    f.write(status + ": " + test_name + "\n")


# ltp log parsing
class LtpParser(object):
    def __init__(self):
        self.results = {}
        self.section = {'duration': "", 'log': ""}

    def parse(self, logfile):
        test_regex = {}
        test_regex['PASSED'] = re.compile(r"PASS")
        test_regex['FAILED'] = re.compile(r"FAIL")
        test_regex['SKIPPED'] = re.compile(r"SKIP")

        with open(logfile, errors='replace') as f:
            for line in f:
                for t in test_regex:
                    result = test_regex[t].search(line)
                    if result:
                        self.results[line.split()[0].strip()] = t

        for test in self.results:
            result = self.results[test]
            self.section['log'] = self.section['log'] + ("%s: %s\n" % (result.strip()[:-2], test.strip()))

        return self.results, self.section


# ltp Compliance log parsing
class LtpComplianceParser(object):
    def __init__(self):
        self.results = {}
        self.section = {'duration': "", 'log': ""}

    def parse(self, logfile):
        test_regex = {}
        test_regex['FAILED'] = re.compile(r"FAIL")

        section_regex = {}
        section_regex['test'] = re.compile(r"^Executing")

        with open(logfile, errors='replace') as f:
            name = logfile
            result = "PASSED"
            for line in f:
                regex_result = section_regex['test'].search(line)
                if regex_result:
                    name = line.split()[1].strip()

                regex_result = test_regex['FAILED'].search(line)
                if regex_result:
                    result = "FAILED"
            self.results[name] = result

        for test in self.results:
            result = self.results[test]
            print (self.results)
            self.section['log'] = self.section['log'] + ("%s: %s\n" % (result.strip()[:-2], test.strip()))

        return self.results, self.section
