#!/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
import textwrap
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=textwrap.dedent(
                    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:])
