#!/usr/bin/env python3
# Copyright 2022 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""check_clang_diags monitors for new diagnostics in LLVM

This looks at projects we care about (currently only clang-tidy, though
hopefully clang in the future, too?) and files bugs whenever a new check or
warning appears. These bugs are intended to keep us up-to-date with new
diagnostics, so we can enable them as they land.
"""

import argparse
import json
import logging
import os
import shutil
import subprocess
import sys
from typing import Dict, List, Tuple

from cros_utils import bugs


_DEFAULT_ASSIGNEE = "mage"
_DEFAULT_CCS = ["cjdb@google.com"]


# FIXME: clang would be cool to check, too? Doesn't seem to have a super stable
# way of listing all warnings, unfortunately.
def _build_llvm(llvm_dir: str, build_dir: str):
    """Builds everything that _collect_available_diagnostics depends on."""
    targets = ["clang-tidy"]
    # use `-C $llvm_dir` so the failure is easier to handle if llvm_dir DNE.
    ninja_result = subprocess.run(
        ["ninja", "-C", build_dir] + targets,
        check=False,
    )
    if not ninja_result.returncode:
        return

    # Sometimes the directory doesn't exist, sometimes incremental cmake
    # breaks, sometimes something random happens. Start fresh since that fixes
    # the issue most of the time.
    logging.warning("Initial build failed; trying to build from scratch.")
    shutil.rmtree(build_dir, ignore_errors=True)
    os.makedirs(build_dir)
    subprocess.run(
        [
            "cmake",
            "-G",
            "Ninja",
            "-DCMAKE_BUILD_TYPE=MinSizeRel",
            "-DLLVM_USE_LINKER=lld",
            "-DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra",
            "-DLLVM_TARGETS_TO_BUILD=X86",
            f"{os.path.abspath(llvm_dir)}/llvm",
        ],
        cwd=build_dir,
        check=True,
    )
    subprocess.run(["ninja"] + targets, check=True, cwd=build_dir)


def _collect_available_diagnostics(
    llvm_dir: str, build_dir: str
) -> Dict[str, List[str]]:
    _build_llvm(llvm_dir, build_dir)

    clang_tidy = os.path.join(os.path.abspath(build_dir), "bin", "clang-tidy")
    clang_tidy_checks = subprocess.run(
        [clang_tidy, "-checks=*", "-list-checks"],
        # Use cwd='/' to ensure no .clang-tidy files are picked up. It
        # _shouldn't_ matter, but it's also ~free, so...
        check=True,
        cwd="/",
        stdout=subprocess.PIPE,
        encoding="utf-8",
    )
    clang_tidy_checks_stdout = [
        x.strip() for x in clang_tidy_checks.stdout.strip().splitlines()
    ]

    # The first line should always be this, then each line thereafter is a check
    # name.
    assert (
        clang_tidy_checks_stdout[0] == "Enabled checks:"
    ), clang_tidy_checks_stdout
    clang_tidy_checks = clang_tidy_checks_stdout[1:]
    assert not any(
        check.isspace() for check in clang_tidy_checks
    ), clang_tidy_checks
    return {"clang-tidy": clang_tidy_checks}


def _process_new_diagnostics(
    old: Dict[str, List[str]], new: Dict[str, List[str]]
) -> Tuple[Dict[str, List[str]], Dict[str, List[str]]]:
    """Determines the set of new diagnostics that we should file bugs for.

    old: The previous state that this function returned as `new_state_file`, or
      `{}`
    new: The diagnostics that we've most recently found. This is a dict in the
      form {tool: [diag]}

    Returns a `new_state_file` to pass into this function as `old` in the
    future, and a dict of diags to file bugs about.
    """
    new_diagnostics = {}
    new_state_file = {}
    for tool, diags in new.items():
        if tool not in old:
            logging.info(
                "New tool with diagnostics: %s; pretending none are new", tool
            )
            new_state_file[tool] = diags
        else:
            old_diags = set(old[tool])
            newly_added_diags = [x for x in diags if x not in old_diags]
            if newly_added_diags:
                new_diagnostics[tool] = newly_added_diags
            # This specifically tries to make diags sticky: if one is landed, then
            # reverted, then relanded, we ignore the reland. This might not be
            # desirable? I don't know.
            new_state_file[tool] = old[tool] + newly_added_diags

    # Sort things so we have more predictable output.
    for v in new_diagnostics.values():
        v.sort()

    return new_state_file, new_diagnostics


def _file_bugs_for_new_diags(new_diags: Dict[str, List[str]]):
    for tool, diags in sorted(new_diags.items()):
        for diag in diags:
            bugs.CreateNewBug(
                component_id=bugs.WellKnownComponents.CrOSToolchainPublic,
                title=f"Investigate {tool} check `{diag}`",
                body="\n".join(
                    (
                        f"It seems that the `{diag}` check was recently added to {tool}.",
                        "It's probably good to TAL at whether this check would be good",
                        "for us to enable in e.g., platform2, or across ChromeOS.",
                    )
                ),
                assignee=_DEFAULT_ASSIGNEE,
                cc=_DEFAULT_CCS,
            )


def main(argv: List[str]):
    logging.basicConfig(
        format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
        "%(message)s",
        level=logging.INFO,
    )

    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument(
        "--llvm_dir", required=True, help="LLVM directory to check. Required."
    )
    parser.add_argument(
        "--llvm_build_dir",
        required=True,
        help="Build directory for LLVM. Required & autocreated.",
    )
    parser.add_argument(
        "--state_file",
        required=True,
        help="State file to use to suppress duplicate complaints. Required.",
    )
    parser.add_argument(
        "--dry_run",
        action="store_true",
        help="Skip filing bugs & writing to the state file; just log "
        "differences.",
    )
    opts = parser.parse_args(argv)

    build_dir = opts.llvm_build_dir
    dry_run = opts.dry_run
    llvm_dir = opts.llvm_dir
    state_file = opts.state_file

    try:
        with open(state_file, encoding="utf-8") as f:
            prior_diagnostics = json.load(f)
    except FileNotFoundError:
        # If the state file didn't exist, just create it without complaining this
        # time.
        prior_diagnostics = {}

    available_diagnostics = _collect_available_diagnostics(llvm_dir, build_dir)
    logging.info("Available diagnostics are %s", available_diagnostics)
    if available_diagnostics == prior_diagnostics:
        logging.info("Current diagnostics are identical to previous ones; quit")
        return

    new_state_file, new_diagnostics = _process_new_diagnostics(
        prior_diagnostics, available_diagnostics
    )
    logging.info("New diagnostics in existing tool(s): %s", new_diagnostics)

    if dry_run:
        logging.info(
            "Skipping new state file writing and bug filing; dry-run "
            "mode wins"
        )
    else:
        _file_bugs_for_new_diags(new_diagnostics)
        new_state_file_path = state_file + ".new"
        with open(new_state_file_path, "w", encoding="utf-8") as f:
            json.dump(new_state_file, f)
        os.rename(new_state_file_path, state_file)


if __name__ == "__main__":
    main(sys.argv[1:])
