#!/usr/bin/env python
#
# Copyright 2018 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# for py2/py3 compatibility
from __future__ import print_function

import json
import multiprocessing
import optparse
import os
import re
import subprocess
import sys

CLANG_TIDY_WARNING = re.compile(r'(\/.*?)\ .*\[(.*)\]$')
CLANG_TIDY_CMDLINE_OUT = re.compile(r'^clang-tidy.*\ .*|^\./\.\*')
FILE_REGEXS = ['../src/*', '../test/*']
HEADER_REGEX = ['\.\.\/src\/.*|\.\.\/include\/.*|\.\.\/test\/.*']

THREADS = multiprocessing.cpu_count()


class ClangTidyWarning(object):
  """
  Wraps up a clang-tidy warning to present aggregated information.
  """

  def __init__(self, warning_type):
    self.warning_type = warning_type
    self.occurrences = set()

  def add_occurrence(self, file_path):
    self.occurrences.add(file_path.lstrip())

  def __hash__(self):
    return hash(self.warning_type)

  def to_string(self, file_loc):
    s = '[%s] #%d\n' % (self.warning_type, len(self.occurrences))
    if file_loc:
      s += ' ' + '\n  '.join(self.occurrences)
      s += '\n'
    return s

  def __str__(self):
    return self.to_string(False)

  def __lt__(self, other):
    return len(self.occurrences) < len(other.occurrences)


def GenerateCompileCommands(build_folder):
  """
  Generate a compilation database.

  Currently clang-tidy-4 does not understand all flags that are passed
  by the build system, therefore, we remove them from the generated file.
  """
  ninja_ps = subprocess.Popen(
    ['ninja', '-t', 'compdb', 'cxx', 'cc'],
    stdout=subprocess.PIPE,
    cwd=build_folder)

  out_filepath = os.path.join(build_folder, 'compile_commands.json')
  with open(out_filepath, 'w') as cc_file:
    while True:
        line = ninja_ps.stdout.readline()

        if line == '':
            break

        line = line.replace('-fcomplete-member-pointers', '')
        line = line.replace('-Wno-enum-compare-switch', '')
        line = line.replace('-Wno-ignored-pragma-optimize', '')
        line = line.replace('-Wno-null-pointer-arithmetic', '')
        line = line.replace('-Wno-unused-lambda-capture', '')
        line = line.replace('-Wno-defaulted-function-deleted', '')
        cc_file.write(line)


def skip_line(line):
  """
  Check if a clang-tidy output line should be skipped.
  """
  return bool(CLANG_TIDY_CMDLINE_OUT.search(line))


def ClangTidyRunFull(build_folder, skip_output_filter, checks, auto_fix):
  """
  Run clang-tidy on the full codebase and print warnings.
  """
  extra_args = []
  if auto_fix:
    extra_args.append('-fix')

  if checks is not None:
    extra_args.append('-checks')
    extra_args.append('-*, ' + checks)

  with open(os.devnull, 'w') as DEVNULL:
    ct_process = subprocess.Popen(
      ['run-clang-tidy', '-j' + str(THREADS), '-p', '.']
       + ['-header-filter'] + HEADER_REGEX + extra_args
       + FILE_REGEXS,
      cwd=build_folder,
      stdout=subprocess.PIPE,
      stderr=DEVNULL)
  removing_check_header = False
  empty_lines = 0

  while True:
    line = ct_process.stdout.readline()
    if line == '':
      break

    # Skip all lines after Enbale checks and before two newlines,
    # i.e., skip clang-tidy check list.
    if line.startswith('Enabled checks'):
      removing_check_header = True
    if removing_check_header and not skip_output_filter:
      if line == '\n':
        empty_lines += 1
      if empty_lines == 2:
        removing_check_header = False
      continue

    # Different lines get removed to ease output reading.
    if not skip_output_filter and skip_line(line):
      continue

    # Print line, because no filter was matched.
    if line != '\n':
        sys.stdout.write(line)


def ClangTidyRunAggregate(build_folder, print_files):
  """
  Run clang-tidy on the full codebase and aggregate warnings into categories.
  """
  with open(os.devnull, 'w') as DEVNULL:
    ct_process = subprocess.Popen(
      ['run-clang-tidy', '-j' + str(THREADS), '-p', '.'] +
        ['-header-filter'] + HEADER_REGEX +
        FILE_REGEXS,
      cwd=build_folder,
      stdout=subprocess.PIPE,
      stderr=DEVNULL)
  warnings = dict()
  while True:
    line = ct_process.stdout.readline()
    if line == '':
      break

    res = CLANG_TIDY_WARNING.search(line)
    if res is not None:
      warnings.setdefault(
          res.group(2),
          ClangTidyWarning(res.group(2))).add_occurrence(res.group(1))

  for warning in sorted(warnings.values(), reverse=True):
    sys.stdout.write(warning.to_string(print_files))


def ClangTidyRunDiff(build_folder, diff_branch, auto_fix):
  """
  Run clang-tidy on the diff between current and the diff_branch.
  """
  if diff_branch is None:
    diff_branch = subprocess.check_output(['git', 'merge-base',
                                           'HEAD', 'origin/master']).strip()

  git_ps = subprocess.Popen(
    ['git', 'diff', '-U0', diff_branch], stdout=subprocess.PIPE)

  extra_args = []
  if auto_fix:
    extra_args.append('-fix')

  with open(os.devnull, 'w') as DEVNULL:
    """
    The script `clang-tidy-diff` does not provide support to add header-
    filters. To still analyze headers we use the build path option `-path` to
    inject our header-filter option. This works because the script just adds
    the passed path string to the commandline of clang-tidy.
    """
    modified_build_folder = build_folder
    modified_build_folder += ' -header-filter='
    modified_build_folder += '\'' + ''.join(HEADER_REGEX) + '\''

    ct_ps = subprocess.Popen(
      ['clang-tidy-diff.py', '-path', modified_build_folder, '-p1'] +
        extra_args,
      stdin=git_ps.stdout,
      stdout=subprocess.PIPE,
      stderr=DEVNULL)
  git_ps.wait()
  while True:
    line = ct_ps.stdout.readline()
    if line == '':
      break

    if skip_line(line):
      continue

    sys.stdout.write(line)


def rm_prefix(string, prefix):
  """
  Removes prefix from a string until the new string
  no longer starts with the prefix.
  """
  while string.startswith(prefix):
    string = string[len(prefix):]
  return string


def ClangTidyRunSingleFile(build_folder, filename_to_check, auto_fix,
                           line_ranges=[]):
  """
  Run clang-tidy on a single file.
  """
  files_with_relative_path = []

  compdb_filepath = os.path.join(build_folder, 'compile_commands.json')
  with open(compdb_filepath) as raw_json_file:
    compdb = json.load(raw_json_file)

  for db_entry in compdb:
    if db_entry['file'].endswith(filename_to_check):
      files_with_relative_path.append(db_entry['file'])

  with open(os.devnull, 'w') as DEVNULL:
    for file_with_relative_path in files_with_relative_path:
      line_filter = None
      if len(line_ranges) != 0:
        line_filter = '['
        line_filter += '{ \"lines\":[' + ', '.join(line_ranges)
        line_filter += '], \"name\":\"'
        line_filter += rm_prefix(file_with_relative_path,
                                 '../') + '\"}'
        line_filter += ']'

      extra_args = ['-line-filter=' + line_filter] if line_filter else []

      if auto_fix:
        extra_args.append('-fix')

      subprocess.call(['clang-tidy', '-p', '.'] +
                      extra_args +
                      [file_with_relative_path],
                      cwd=build_folder,
                      stderr=DEVNULL)


def CheckClangTidy():
  """
  Checks if a clang-tidy binary exists.
  """
  with open(os.devnull, 'w') as DEVNULL:
    return subprocess.call(['which', 'clang-tidy'], stdout=DEVNULL) == 0


def CheckCompDB(build_folder):
  """
  Checks if a compilation database exists in the build_folder.
  """
  return os.path.isfile(os.path.join(build_folder, 'compile_commands.json'))


def DetectBuildFolder():
    """
    Tries to auto detect the last used build folder in out/
    """
    outdirs_folder = 'out/'
    last_used = None
    last_timestamp = -1
    for outdir in [outdirs_folder + folder_name
                   for folder_name in os.listdir(outdirs_folder)
                   if os.path.isdir(outdirs_folder + folder_name)]:
        outdir_modified_timestamp = os.path.getmtime(outdir)
        if  outdir_modified_timestamp > last_timestamp:
            last_timestamp = outdir_modified_timestamp
            last_used = outdir

    return last_used


def GetOptions():
  """
  Generate the option parser for this script.
  """
  result = optparse.OptionParser()
  result.add_option(
    '-b',
    '--build-folder',
    help='Set V8 build folder',
    dest='build_folder',
    default=None)
  result.add_option(
    '-j',
    help='Set the amount of threads that should be used',
    dest='threads',
    default=None)
  result.add_option(
    '--gen-compdb',
    help='Generate a compilation database for clang-tidy',
    default=False,
    action='store_true')
  result.add_option(
    '--no-output-filter',
    help='Done use any output filterning',
    default=False,
    action='store_true')
  result.add_option(
    '--fix',
    help='Fix auto fixable issues',
    default=False,
    dest='auto_fix',
    action='store_true'
  )

  # Full clang-tidy.
  full_run_g = optparse.OptionGroup(result, 'Clang-tidy full', '')
  full_run_g.add_option(
    '--full',
    help='Run clang-tidy on the whole codebase',
    default=False,
    action='store_true')
  full_run_g.add_option('--checks',
                        help='Clang-tidy checks to use.',
                        default=None)
  result.add_option_group(full_run_g)

  # Aggregate clang-tidy.
  agg_run_g = optparse.OptionGroup(result, 'Clang-tidy aggregate', '')
  agg_run_g.add_option('--aggregate', help='Run clang-tidy on the whole '\
             'codebase and aggregate the warnings',
             default=False, action='store_true')
  agg_run_g.add_option('--show-loc', help='Show file locations when running '\
             'in aggregate mode', default=False,
             action='store_true')
  result.add_option_group(agg_run_g)

  # Diff clang-tidy.
  diff_run_g = optparse.OptionGroup(result, 'Clang-tidy diff', '')
  diff_run_g.add_option('--branch', help='Run clang-tidy on the diff '\
             'between HEAD and the merge-base between HEAD '\
             'and DIFF_BRANCH (origin/master by default).',
             default=None, dest='diff_branch')
  result.add_option_group(diff_run_g)

  # Single clang-tidy.
  single_run_g = optparse.OptionGroup(result, 'Clang-tidy single', '')
  single_run_g.add_option(
    '--single', help='', default=False, action='store_true')
  single_run_g.add_option(
    '--file', help='File name to check', default=None, dest='file_name')
  single_run_g.add_option('--lines', help='Limit checks to a line range. '\
              'For example: --lines="[2,4], [5,6]"',
              default=[], dest='line_ranges')

  result.add_option_group(single_run_g)
  return result


def main():
  parser = GetOptions()
  (options, _) = parser.parse_args()

  if options.threads is not None:
    global THREADS
    THREADS = options.threads

  if options.build_folder is None:
    options.build_folder = DetectBuildFolder()

  if not CheckClangTidy():
    print('Could not find clang-tidy')
  elif options.build_folder is None or not os.path.isdir(options.build_folder):
    print('Please provide a build folder with -b')
  elif options.gen_compdb:
    GenerateCompileCommands(options.build_folder)
  elif not CheckCompDB(options.build_folder):
    print('Could not find compilation database, ' \
      'please generate it with --gen-compdb')
  else:
    print('Using build folder:', options.build_folder)
    if options.full:
      print('Running clang-tidy - full')
      ClangTidyRunFull(options.build_folder,
                       options.no_output_filter,
                       options.checks,
                       options.auto_fix)
    elif options.aggregate:
      print('Running clang-tidy - aggregating warnings')
      if options.auto_fix:
        print('Auto fix not working in aggregate mode, running without.')
      ClangTidyRunAggregate(options.build_folder, options.show_loc)
    elif options.single:
      print('Running clang-tidy - single on ' + options.file_name)
      if options.file_name is not None:
        line_ranges = []
        for match in re.findall(r'(\[.*?\])', options.line_ranges):
          if match is not []:
            line_ranges.append(match)
        ClangTidyRunSingleFile(options.build_folder,
                               options.file_name,
                               options.auto_fix,
                               line_ranges)
      else:
        print('Filename provided, please specify a filename with --file')
    else:
      print('Running clang-tidy')
      ClangTidyRunDiff(options.build_folder,
                       options.diff_branch,
                       options.auto_fix)


if __name__ == '__main__':
  main()
