#!/usr/bin/env python3
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
r"""Parses lint report and dump filtered messages in hjson format.
"""
import argparse
import re
import sys
from pathlib import Path

import hjson


def extract_messages(full_file, patterns, results):
    """
    This extracts messages from the sting buffer full_file.
    The argument patterns needs to be a list of tuples with
    (<error_severity>, <pattern_to_match_for>).
    """
    for severity, pattern in patterns:
        results[severity] += re.findall(pattern, full_file, flags=re.MULTILINE)

    return results


def get_results(resdir):
    """
    Parse report and corresponding logfiles and extract error, warning
    and info messages for each IP present in the result folder
    """
    results = {
        "tool": "ascentlint",
        "errors": [],
        "warnings": [],
        "lint_errors": [],
        "lint_warnings": [],
        "lint_infos": []
    }
    try:
        # check the log file for flow errors and warnings
        with Path(resdir).joinpath('ascentlint.log').open() as f:
            full_file = f.read()
            err_warn_patterns = [("errors", r"^FlexNet Licensing error.*"),
                                 ("errors", r"^Error: .*"),
                                 ("errors", r"^  ERR .*"),
                                 ("warnings", r"^Warning: .*"),
                                 ("warnings", r"^  WARN .*")]
            extract_messages(full_file, err_warn_patterns, results)
    except IOError as err:
        results["errors"] += ["IOError: %s" % err]

    try:
        # check the report file for lint INFO, WARNING and ERRORs
        with Path(resdir).joinpath('ascentlint.rpt').open() as f:
            full_file = f.read()
            err_warn_patterns = {("lint_errors", r"^E  .*"),
                                 ("lint_warnings", r"^W  .*"),
                                 ("lint_infos", r"^I  .*")}
            extract_messages(full_file, err_warn_patterns, results)
    except IOError as err:
        results["errors"] += ["IOError: %s" % err]

    return results


def main():

    parser = argparse.ArgumentParser(
        description="""This script parses AscentLint log and report files from
        a lint run, filters the messages and creates an aggregated result
        .hjson file with the following fields:

           {"tool": "ascentlint",
            "errors" : [],
            "warnings" : [],
            "lint_errors" : [],
            "lint_warnings" : [],
            "lint_infos" : []}

        The fields 'errors' and 'warnings' contain file IO messages or
        messages output by the tool itself, whereas the fields prefixed with
        'lint_' contain lint-related messages.

        The script returns nonzero status if any warnings or errors are present.
        """)
    parser.add_argument('--repdir',
                        type=str,
                        default="./",
                        help="""The script searches the 'ascentlint.log' and
                        'ascentlint.rpt' files in this directory.
                        Defaults to './'""")

    parser.add_argument('--outdir',
                        type=str,
                        default="./",
                        help="""Output directory for the 'results.hjson' file.
                        Defaults to './'""")

    args = parser.parse_args()
    results = get_results(args.repdir)

    with Path(args.outdir).joinpath("results.hjson").open("w") as results_file:
        hjson.dump(results,
                   results_file,
                   ensure_ascii=False,
                   for_json=True,
                   use_decimal=True)

    # return nonzero status if any warnings or errors are present
    # lint infos do not count as failures
    nr_errors = len(results["errors"]) + len(results["lint_errors"])
    nr_warnings = len(results["warnings"]) + len(results["lint_warnings"])
    if nr_errors > 0 or nr_warnings > 0:
        print("Lint not successful, got %d warnings and %d errors." %
              (nr_warnings, nr_errors))
        sys.exit(1)

    print("Lint successful, got %d warnings and %d errors." %
          (nr_warnings, nr_errors))
    sys.exit(0)


if __name__ == "__main__":
    main()
