#!/usr/bin/env python3
#
# ===- rename_check.py - clang-tidy check renamer ------------*- python -*--===#
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# ===-----------------------------------------------------------------------===#

import argparse
import glob
import io
import os
import re
import sys
from typing import List


def replaceInFileRegex(fileName: str, sFrom: str, sTo: str) -> None:
    if sFrom == sTo:
        return

    # The documentation files are encoded using UTF-8, however on Windows the
    # default encoding might be different (e.g. CP-1252). To make sure UTF-8 is
    # always used, use `io.open(filename, mode, encoding='utf8')` for reading and
    # writing files here and elsewhere.
    txt = None
    with io.open(fileName, "r", encoding="utf8") as f:
        txt = f.read()

    txt = re.sub(sFrom, sTo, txt)
    print("Replacing '%s' -> '%s' in '%s'..." % (sFrom, sTo, fileName))
    with io.open(fileName, "w", encoding="utf8") as f:
        f.write(txt)


def replaceInFile(fileName: str, sFrom: str, sTo: str) -> None:
    if sFrom == sTo:
        return
    txt = None
    with io.open(fileName, "r", encoding="utf8") as f:
        txt = f.read()

    if sFrom not in txt:
        return

    txt = txt.replace(sFrom, sTo)
    print("Replacing '%s' -> '%s' in '%s'..." % (sFrom, sTo, fileName))
    with io.open(fileName, "w", encoding="utf8") as f:
        f.write(txt)


def generateCommentLineHeader(filename: str) -> str:
    return "".join(
        [
            "//===--- ",
            os.path.basename(filename),
            " - clang-tidy ",
            "-" * max(0, 42 - len(os.path.basename(filename))),
            "*- C++ -*-===//",
        ]
    )


def generateCommentLineSource(filename: str) -> str:
    return "".join(
        [
            "//===--- ",
            os.path.basename(filename),
            " - clang-tidy",
            "-" * max(0, 52 - len(os.path.basename(filename))),
            "-===//",
        ]
    )


def fileRename(fileName: str, sFrom: str, sTo: str) -> str:
    if sFrom not in fileName or sFrom == sTo:
        return fileName
    newFileName = fileName.replace(sFrom, sTo)
    print("Renaming '%s' -> '%s'..." % (fileName, newFileName))
    os.rename(fileName, newFileName)
    return newFileName


def deleteMatchingLines(fileName: str, pattern: str) -> bool:
    lines = None
    with io.open(fileName, "r", encoding="utf8") as f:
        lines = f.readlines()

    not_matching_lines = [l for l in lines if not re.search(pattern, l)]
    if len(not_matching_lines) == len(lines):
        return False

    print("Removing lines matching '%s' in '%s'..." % (pattern, fileName))
    print("  " + "  ".join([l for l in lines if re.search(pattern, l)]))
    with io.open(fileName, "w", encoding="utf8") as f:
        f.writelines(not_matching_lines)

    return True


def getListOfFiles(clang_tidy_path: str) -> List[str]:
    files = glob.glob(os.path.join(clang_tidy_path, "**"), recursive=True)
    files += [
        os.path.normpath(os.path.join(clang_tidy_path, "../docs/ReleaseNotes.rst"))
    ]
    files += glob.glob(
        os.path.join(clang_tidy_path, "..", "test", "clang-tidy", "checkers", "**"),
        recursive=True,
    )
    files += glob.glob(
        os.path.join(clang_tidy_path, "..", "docs", "clang-tidy", "checks", "*.rst")
    )
    files += glob.glob(
        os.path.join(
            clang_tidy_path, "..", "docs", "clang-tidy", "checks", "*", "*.rst"
        ),
        recursive=True,
    )
    return [filename for filename in files if os.path.isfile(filename)]


# Adapts the module's CMakelist file. Returns 'True' if it could add a new
# entry and 'False' if the entry already existed.
def adapt_cmake(module_path: str, check_name_camel: str) -> bool:
    filename = os.path.join(module_path, "CMakeLists.txt")
    with io.open(filename, "r", encoding="utf8") as f:
        lines = f.readlines()

    cpp_file = check_name_camel + ".cpp"

    # Figure out whether this check already exists.
    for line in lines:
        if line.strip() == cpp_file:
            return False

    print("Updating %s..." % filename)
    with io.open(filename, "w", encoding="utf8") as f:
        cpp_found = False
        file_added = False
        for line in lines:
            cpp_line = line.strip().endswith(".cpp")
            if (not file_added) and (cpp_line or cpp_found):
                cpp_found = True
                if (line.strip() > cpp_file) or (not cpp_line):
                    f.write("  " + cpp_file + "\n")
                    file_added = True
            f.write(line)

    return True


# Modifies the module to include the new check.
def adapt_module(
    module_path: str, module: str, check_name: str, check_name_camel: str
) -> None:
    modulecpp = next(
        iter(
            filter(
                lambda p: p.lower() == module.lower() + "tidymodule.cpp",
                os.listdir(module_path),
            )
        )
    )
    filename = os.path.join(module_path, modulecpp)
    with io.open(filename, "r", encoding="utf8") as f:
        lines = f.readlines()

    print("Updating %s..." % filename)
    with io.open(filename, "w", encoding="utf8") as f:
        header_added = False
        header_found = False
        check_added = False
        check_decl = (
            "    CheckFactories.registerCheck<"
            + check_name_camel
            + '>(\n        "'
            + check_name
            + '");\n'
        )

        for line in lines:
            if not header_added:
                match = re.search('#include "(.*)"', line)
                if match:
                    header_found = True
                    if match.group(1) > check_name_camel:
                        header_added = True
                        f.write('#include "' + check_name_camel + '.h"\n')
                elif header_found:
                    header_added = True
                    f.write('#include "' + check_name_camel + '.h"\n')

            if not check_added:
                if line.strip() == "}":
                    check_added = True
                    f.write(check_decl)
                else:
                    match = re.search("registerCheck<(.*)>", line)
                    if match and match.group(1) > check_name_camel:
                        check_added = True
                        f.write(check_decl)
            f.write(line)


# Adds a release notes entry.
def add_release_notes(
    clang_tidy_path: str, old_check_name: str, new_check_name: str
) -> None:
    filename = os.path.normpath(
        os.path.join(clang_tidy_path, "../docs/ReleaseNotes.rst")
    )
    with io.open(filename, "r", encoding="utf8") as f:
        lines = f.readlines()

    lineMatcher = re.compile("Renamed checks")
    nextSectionMatcher = re.compile("Improvements to include-fixer")
    checkMatcher = re.compile("- The '(.*)")

    print("Updating %s..." % filename)
    with io.open(filename, "w", encoding="utf8") as f:
        note_added = False
        header_found = False
        add_note_here = False

        for line in lines:
            if not note_added:
                match = lineMatcher.match(line)
                match_next = nextSectionMatcher.match(line)
                match_check = checkMatcher.match(line)
                if match_check:
                    last_check = match_check.group(1)
                    if last_check > old_check_name:
                        add_note_here = True

                if match_next:
                    add_note_here = True

                if match:
                    header_found = True
                    f.write(line)
                    continue

                if line.startswith("^^^^"):
                    f.write(line)
                    continue

                if header_found and add_note_here:
                    if not line.startswith("^^^^"):
                        f.write(
                            """- The '%s' check was renamed to :doc:`%s
  <clang-tidy/checks/%s/%s>`

                    """
                            % (
                                old_check_name,
                                new_check_name,
                                new_check_name.split("-", 1)[0],
                                "-".join(new_check_name.split("-")[1:]),
                            )
                        )
                        note_added = True

            f.write(line)


def main() -> None:
    parser = argparse.ArgumentParser(description="Rename clang-tidy check.")
    parser.add_argument("old_check_name", type=str, help="Old check name.")
    parser.add_argument("new_check_name", type=str, help="New check name.")
    parser.add_argument(
        "--check_class_name",
        type=str,
        help="Old name of the class implementing the check.",
    )
    args = parser.parse_args()

    old_module = args.old_check_name.split("-")[0]
    new_module = args.new_check_name.split("-")[0]
    old_name = "-".join(args.old_check_name.split("-")[1:])
    new_name = "-".join(args.new_check_name.split("-")[1:])

    if args.check_class_name:
        check_name_camel = args.check_class_name
    else:
        check_name_camel = (
            "".join(map(lambda elem: elem.capitalize(), old_name.split("-"))) + "Check"
        )

    new_check_name_camel = (
        "".join(map(lambda elem: elem.capitalize(), new_name.split("-"))) + "Check"
    )

    clang_tidy_path = os.path.dirname(__file__)

    header_guard_variants = [
        (args.old_check_name.replace("-", "_")).upper() + "_CHECK",
        (old_module + "_" + check_name_camel).upper(),
        (old_module + "_" + new_check_name_camel).upper(),
        args.old_check_name.replace("-", "_").upper(),
    ]
    header_guard_new = (new_module + "_" + new_check_name_camel).upper()

    old_module_path = os.path.join(clang_tidy_path, old_module)
    new_module_path = os.path.join(clang_tidy_path, new_module)

    if old_module != new_module:
        # Remove the check from the old module.
        cmake_lists = os.path.join(old_module_path, "CMakeLists.txt")
        check_found = deleteMatchingLines(cmake_lists, "\\b" + check_name_camel)
        if not check_found:
            print(
                "Check name '%s' not found in %s. Exiting."
                % (check_name_camel, cmake_lists)
            )
            sys.exit(1)

        modulecpp = next(
            iter(
                filter(
                    lambda p: p.lower() == old_module.lower() + "tidymodule.cpp",
                    os.listdir(old_module_path),
                )
            )
        )
        deleteMatchingLines(
            os.path.join(old_module_path, modulecpp),
            "\\b" + check_name_camel + "|\\b" + args.old_check_name,
        )

    for filename in getListOfFiles(clang_tidy_path):
        originalName = filename
        filename = fileRename(
            filename, old_module + "/" + old_name, new_module + "/" + new_name
        )
        filename = fileRename(filename, args.old_check_name, args.new_check_name)
        filename = fileRename(filename, check_name_camel, new_check_name_camel)
        replaceInFile(
            filename,
            generateCommentLineHeader(originalName),
            generateCommentLineHeader(filename),
        )
        replaceInFile(
            filename,
            generateCommentLineSource(originalName),
            generateCommentLineSource(filename),
        )
        for header_guard in header_guard_variants:
            replaceInFile(filename, header_guard, header_guard_new)

        if new_module + "/" + new_name + ".rst" in filename:
            replaceInFile(
                filename,
                args.old_check_name + "\n" + "=" * len(args.old_check_name) + "\n",
                args.new_check_name + "\n" + "=" * len(args.new_check_name) + "\n",
            )

        replaceInFile(filename, args.old_check_name, args.new_check_name)
        replaceInFile(
            filename,
            old_module + "::" + check_name_camel,
            new_module + "::" + new_check_name_camel,
        )
        replaceInFile(
            filename,
            old_module + "/" + check_name_camel,
            new_module + "/" + new_check_name_camel,
        )
        replaceInFile(
            filename, old_module + "/" + old_name, new_module + "/" + new_name
        )
        replaceInFile(filename, check_name_camel, new_check_name_camel)

    if old_module != new_module or new_module == "llvm":
        if new_module == "llvm":
            new_namespace = new_module + "_check"
        else:
            new_namespace = new_module
        check_implementation_files = glob.glob(
            os.path.join(old_module_path, new_check_name_camel + "*")
        )
        for filename in check_implementation_files:
            # Move check implementation to the directory of the new module.
            filename = fileRename(filename, old_module_path, new_module_path)
            replaceInFileRegex(
                filename,
                "namespace clang::tidy::" + old_module + "[^ \n]*",
                "namespace clang::tidy::" + new_namespace,
            )

    if old_module != new_module:

        # Add check to the new module.
        adapt_cmake(new_module_path, new_check_name_camel)
        adapt_module(
            new_module_path, new_module, args.new_check_name, new_check_name_camel
        )

    os.system(os.path.join(clang_tidy_path, "add_new_check.py") + " --update-docs")
    add_release_notes(clang_tidy_path, args.old_check_name, args.new_check_name)


if __name__ == "__main__":
    main()
