"""
Parses compiler output from Clang or GCC and checks that warnings
exist only in files that are expected to have warnings.
"""

import argparse
import re
import sys
from collections import defaultdict
from pathlib import Path
from typing import NamedTuple, TypedDict


class IgnoreRule(NamedTuple):
    file_path: str
    count: int  # type: ignore[assignment]
    ignore_all: bool = False
    is_directory: bool = False


class CompileWarning(TypedDict):
    file: str
    line: str
    column: str
    message: str
    option: str


def parse_warning_ignore_file(file_path: str) -> set[IgnoreRule]:
    """
    Parses the warning ignore file and returns a set of IgnoreRules
    """
    files_with_expected_warnings: set[IgnoreRule] = set()
    with Path(file_path).open(encoding="UTF-8") as ignore_rules_file:
        files_with_expected_warnings = set()
        for i, line in enumerate(ignore_rules_file):
            line = line.strip()
            if line and not line.startswith("#"):
                line_parts = line.split()
                if len(line_parts) >= 2:
                    file_name = line_parts[0]
                    count = line_parts[1]
                    ignore_all = count == "*"
                    is_directory = file_name.endswith("/")

                    # Directories must have a wildcard count
                    if is_directory and count != "*":
                        print(
                            f"Error parsing ignore file: {file_path} "
                            f"at line: {i}"
                        )
                        print(
                            f"Directory {file_name} must have count set to *"
                        )
                        sys.exit(1)
                    if ignore_all:
                        count = "0"

                    files_with_expected_warnings.add(
                        IgnoreRule(
                            file_name, int(count), ignore_all, is_directory
                        )
                    )

    return files_with_expected_warnings


def extract_warnings_from_compiler_output(
    compiler_output: str,
    compiler_output_type: str,
    path_prefix: str = "",
) -> list[CompileWarning]:
    """
    Extracts warnings from the compiler output based on compiler
    output type. Removes path prefix from file paths if provided.
    Compatible with GCC and Clang compiler output.
    """
    # Choose pattern and compile regex for particular compiler output
    if compiler_output_type == "gcc":
        regex_pattern = (
            r"(?P<file>.*):(?P<line>\d+):(?P<column>\d+): warning: "
            r"(?P<message>.*?)(?: (?P<option>\[-[^\]]+\]))?$"
        )
    elif compiler_output_type == "clang":
        regex_pattern = (
            r"(?P<file>.*):(?P<line>\d+):(?P<column>\d+): warning: "
            r"(?P<message>.*) (?P<option>\[-[^\]]+\])$"
        )
    else:
        raise RuntimeError(
            f"Unsupported compiler output type: {compiler_output_type}",
        )
    compiled_regex = re.compile(regex_pattern)
    compiler_warnings: list[CompileWarning] = []
    for i, line in enumerate(compiler_output.splitlines(), start=1):
        if match := compiled_regex.match(line):
            try:
                compiler_warnings.append({
                    "file": match.group("file").removeprefix(path_prefix),
                    "line": match.group("line"),
                    "column": match.group("column"),
                    "message": match.group("message"),
                    "option": match.group("option").lstrip("[").rstrip("]"),
                })
            except AttributeError:
                print(
                    f"Error parsing compiler output. "
                    f"Unable to extract warning on line {i}:\n{line}"
                )
                sys.exit(1)

    return compiler_warnings


def get_warnings_by_file(
    warnings: list[CompileWarning],
) -> dict[str, list[CompileWarning]]:
    """
    Returns a dictionary where the key is the file and the data is the
    warnings in that file. Does not include duplicate warnings for a
    file from list of provided warnings.
    """
    warnings_by_file = defaultdict(list)
    warnings_added = set()
    for warning in warnings:
        warning_key = (
            f"{warning['file']}-{warning['line']}-"
            f"{warning['column']}-{warning['option']}"
        )
        if warning_key not in warnings_added:
            warnings_added.add(warning_key)
            warnings_by_file[warning["file"]].append(warning)

    return warnings_by_file


def is_file_ignored(
    file_path: str, ignore_rules: set[IgnoreRule]
) -> IgnoreRule | None:
    """Return the IgnoreRule object for the file path.

    Return ``None`` if there is no related rule for that path.
    """
    for rule in ignore_rules:
        if rule.is_directory:
            if file_path.startswith(rule.file_path):
                return rule
        elif file_path == rule.file_path:
            return rule
    return None


def get_unexpected_warnings(
    ignore_rules: set[IgnoreRule],
    files_with_warnings: dict[str, list[CompileWarning]],
) -> int:
    """
    Returns failure status if warnings discovered in list of warnings
    are associated with a file that is not found in the list of files
    with expected warnings
    """
    unexpected_warnings = {}
    for file in files_with_warnings.keys():
        rule = is_file_ignored(file, ignore_rules)

        if rule:
            if rule.ignore_all:
                continue

            if len(files_with_warnings[file]) > rule.count:
                unexpected_warnings[file] = (
                    files_with_warnings[file],
                    rule.count,
                )
            continue
        elif rule is None:
            # If the file is not in the ignore list, then it is unexpected
            unexpected_warnings[file] = (files_with_warnings[file], 0)

    if unexpected_warnings:
        print("Unexpected warnings:")
        for file in unexpected_warnings:
            print(
                f"{file} expected {unexpected_warnings[file][1]} warnings,"
                f" found {len(unexpected_warnings[file][0])}"
            )
            for warning in unexpected_warnings[file][0]:
                print(warning)

        return 1

    return 0


def get_unexpected_improvements(
    ignore_rules: set[IgnoreRule],
    files_with_warnings: dict[str, list[CompileWarning]],
) -> int:
    """
    Returns failure status if the number of warnings for a file is greater
    than the expected number of warnings for that file based on the ignore
    rules
    """
    unexpected_improvements = []
    for rule in ignore_rules:
        if (
            not rule.ignore_all
            and rule.file_path not in files_with_warnings.keys()
        ):
            if rule.file_path not in files_with_warnings.keys():
                unexpected_improvements.append((rule.file_path, rule.count, 0))
            elif len(files_with_warnings[rule.file_path]) < rule.count:
                unexpected_improvements.append((
                    rule.file_path,
                    rule.count,
                    len(files_with_warnings[rule.file_path]),
                ))

    if unexpected_improvements:
        print("Unexpected improvements:")
        for file in unexpected_improvements:
            print(f"{file[0]} expected {file[1]} warnings, found {file[2]}")
        return 1

    return 0


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-c",
        "--compiler-output-file-path",
        type=str,
        required=True,
        help="Path to the compiler output file",
    )
    parser.add_argument(
        "-i",
        "--warning-ignore-file-path",
        type=str,
        help="Path to the warning ignore file",
    )
    parser.add_argument(
        "-x",
        "--fail-on-regression",
        action="store_true",
        default=False,
        help="Flag to fail if new warnings are found",
    )
    parser.add_argument(
        "-X",
        "--fail-on-improvement",
        action="store_true",
        default=False,
        help="Flag to fail if files that were expected "
        "to have warnings have no warnings",
    )
    parser.add_argument(
        "-t",
        "--compiler-output-type",
        type=str,
        required=True,
        choices=["gcc", "clang"],
        help="Type of compiler output file (GCC or Clang)",
    )
    parser.add_argument(
        "-p",
        "--path-prefix",
        type=str,
        help="Path prefix to remove from the start of file paths"
        " in compiler output",
    )

    args = parser.parse_args(argv)

    exit_code = 0

    # Check that the compiler output file is a valid path
    if not Path(args.compiler_output_file_path).is_file():
        print(
            f"Compiler output file does not exist:"
            f" {args.compiler_output_file_path}"
        )
        return 1

    # Check that a warning ignore file was specified and if so is a valid path
    if not args.warning_ignore_file_path:
        print(
            "Warning ignore file not specified."
            " Continuing without it (no warnings ignored)."
        )
        ignore_rules = set()
    else:
        if not Path(args.warning_ignore_file_path).is_file():
            print(
                f"Warning ignore file does not exist:"
                f" {args.warning_ignore_file_path}"
            )
            return 1
        ignore_rules = parse_warning_ignore_file(args.warning_ignore_file_path)

    with Path(args.compiler_output_file_path).open(encoding="UTF-8") as f:
        compiler_output_file_contents = f.read()

    warnings = extract_warnings_from_compiler_output(
        compiler_output_file_contents,
        args.compiler_output_type,
        args.path_prefix,
    )

    files_with_warnings = get_warnings_by_file(warnings)

    status = get_unexpected_warnings(ignore_rules, files_with_warnings)
    if args.fail_on_regression:
        exit_code |= status

    status = get_unexpected_improvements(ignore_rules, files_with_warnings)
    if args.fail_on_improvement:
        exit_code |= status

    print(
        "For information about this tool and its configuration"
        " visit https://devguide.python.org/development-tools/warnings/"
    )

    return exit_code


if __name__ == "__main__":
    sys.exit(main())
