#!/usr/bin/env python
#
#===- 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 os
import re


def replaceInFileRegex(fileName, sFrom, sTo):
  if sFrom == sTo:
    return
  txt = None
  with open(fileName, "r") as f:
    txt = f.read()

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

def replaceInFile(fileName, sFrom, sTo):
  if sFrom == sTo:
    return
  txt = None
  with open(fileName, "r") 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 open(fileName, "w") 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 open(fileName, "r") 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 open(fileName, "w") as f:
    f.writelines(not_matching_lines)

  return True

def getListOfFiles(clang_tidy_path):
  files = glob.glob(os.path.join(clang_tidy_path, '*'))
  for dirname in files:
    if os.path.isdir(dirname):
      files += glob.glob(os.path.join(dirname, '*'))
  files += glob.glob(os.path.join(clang_tidy_path, '..', 'test',
                                  'clang-tidy', '*'))
  files += glob.glob(os.path.join(clang_tidy_path, '..', 'docs',
                                  'clang-tidy', 'checks', '*'))
  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 open(filename, 'r') 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 open(filename, 'wb') 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 = filter(lambda p: p.lower() == module.lower() + 'tidymodule.cpp',
                     os.listdir(module_path))[0]
  filename = os.path.join(module_path, modulecpp)
  with open(filename, 'r') as f:
    lines = f.readlines()

  print('Updating %s...' % filename)
  with open(filename, 'wb') 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 open(filename, 'r') 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 open(filename, 'wb') as f:
    note_added = False
    header_found = False
    next_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:
          next_header_found = True
          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>`

""" % (old_check_name, new_check_name, new_check_name))
            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]
  if args.check_class_name:
    check_name_camel = args.check_class_name
  else:
    check_name_camel = (''.join(map(lambda elem: elem.capitalize(),
                                    args.old_check_name.split('-')[1:])) +
                        'Check')

  new_check_name_camel = (''.join(map(lambda elem: elem.capitalize(),
                                      args.new_check_name.split('-')[1:])) +
                          '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 (args.old_check_name != args.new_check_name):
    # 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 = filter(
        lambda p: p.lower() == old_module.lower() + 'tidymodule.cpp',
        os.listdir(old_module_path))[0]
    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, 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 args.new_check_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, 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 ' + old_module + '[^ \n]*',
                         'namespace ' + new_namespace)

  if (args.old_check_name == args.new_check_name):
    return

  # 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()
