#!/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 += 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', '*'))
  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>`

""" % (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 = 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)

  old_check_filename = '-'.join(args.old_check_name.split('-')[1:])
  new_check_filename = '-'.join(args.new_check_name.split('-')[1:])

  for filename in getListOfFiles(clang_tidy_path):
    originalName = filename
    filename = fileRename(filename, old_check_filename, new_check_filename)
    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 clang::tidy::' + old_module + '[^ \n]*',
                         'namespace clang::tidy::' + 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()
