#!/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": "veriblelint",
        "errors": [],
        "warnings": [],
        "lint_errors": [],
        "lint_warnings": [],
        "lint_infos": []
    }
    try:
        # check the report file for lint INFO, WARNING and ERRORs
        with Path(resdir).joinpath('lint.log').open() as f:
            full_file = f.read()
            err_warn_patterns = {
                # The lint failed error can be ignored, since
                # Fusesoc will always return this error if lint warnings have
                # been found. We have a way of capturing the lint warnings
                # explicitly in this parsing script, hence this error is redundant
                # and we decided not to report it in the dashboard.
                ("errors",
                 r"^(?!ERROR: Failed to run .* Lint failed)ERROR: .*"),
                ("errors", r"^Error: .*"),
                ("errors", r"^E .*"),
                # TODO(https://github.com/olofk/edalize/issues/90):
                # this is a workaround until we actually have native Edalize
                # support for JasperGold and "formal" targets
                ("warnings",
                 r"^(?!WARNING: Unknown item formal in section Target)WARNING: .*"
                 # TODO(https://github.com/lowRISC/ibex/issues/1033):
                 # remove once this has been fixed in Edalize or in the corefile.
                 r"^(?!WARNING: Unknown item symbiyosis in section Target)WARNING: .*"
                 ),
                ("warnings", r"^Warning: .* "),
                ("warnings", r"^W .*"),
                ("lint_warnings", r"^.*\[Style:.*")
            }
            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 verible lint log files from
        a lint run, filters the messages and creates an aggregated result
        .hjson file with the following fields:

           {"tool": "veriblelint",
            "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 'lint.log'
                        files in this directory.
                        Defaults to './'""")

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

    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"])
    print("Lint not successful, got %d warnings and %d errors." %
          (nr_warnings, nr_errors))
    if nr_errors > 0 or nr_warnings > 0:
        sys.exit(1)
    sys.exit(0)


if __name__ == "__main__":
    main()
