#!/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
#
# ===-----------------------------------------------------------------------===#

from __future__ import unicode_literals

import argparse
import glob
import io
import os
import re


def replaceInFileRegex(fileName, sFrom, sTo):
    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, sFrom, sTo):
    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):
    return "".join(
        [
            "//===--- ",
            os.path.basename(filename),
            " - clang-tidy ",
            "-" * max(0, 42 - len(os.path.basename(filename))),
            "*- C++ -*-===//",
        ]
    )


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


def fileRename(fileName, sFrom, sTo):
    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, pattern):
    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):
    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, check_name_camel):
    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, module, check_name, check_name_camel):
    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, old_check_name, new_check_name):
    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():
    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)
            )
            return 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()
