#!/usr/bin/env python
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
r"""Automatically fetch, build, and run clang-tidy from source.

This script seeks to automate the steps detailed in docs/clang_tidy.md.

Example: the following command disables clang-tidy's default checks (-*) and
enables the clang static analyzer checks.

    tools/clang/scripts/clang_tidy_tool.py \\
       --checks='-*,clang-analyzer-*,-clang-analyzer-alpha*' \\
       --header-filter='.*' \\
       out/Release chrome

The same, but checks the changes only.

    git diff -U5 | tools/clang/scripts/clang_tidy_tool.py \\
       --diff \\
       --checks='-*,clang-analyzer-*,-clang-analyzer-alpha*' \\
       --header-filter='.*' \\
       out/Release chrome
"""

import argparse
import os
import subprocess
import sys

import build_clang_tools_extra


def GetBinaryPath(build_dir, binary):
  if sys.platform == 'win32':
    binary += '.exe'
  return os.path.join(build_dir, 'bin', binary)


def BuildNinjaTarget(out_dir, ninja_target):
  args = ['autoninja', '-C', out_dir, ninja_target]
  subprocess.check_call(args, shell=sys.platform == 'win32')


def GenerateCompDb(out_dir):
  gen_compdb_script = os.path.join(
      os.path.dirname(__file__), 'generate_compdb.py')
  comp_db_file_path = os.path.join(out_dir, 'compile_commands.json')
  args = [
      sys.executable,
      gen_compdb_script,
      '-p',
      out_dir,
      '-o',
      comp_db_file_path,
  ]
  subprocess.check_call(args)

  # The resulting CompDb file includes /showIncludes which causes clang-tidy to
  # output a lot of unnecessary text to the console.
  with open(comp_db_file_path, 'r') as comp_db_file:
    comp_db_data = comp_db_file.read()

  # The trailing space on /showIncludes helps keep single-spaced flags.
  comp_db_data = comp_db_data.replace('/showIncludes ', '')

  with open(comp_db_file_path, 'w') as comp_db_file:
    comp_db_file.write(comp_db_data)


def RunClangTidy(checks, header_filter, auto_fix, clang_src_dir,
                 clang_build_dir, out_dir, ninja_target):
  """Invoke the |run-clang-tidy.py| script."""
  run_clang_tidy_script = os.path.join(clang_src_dir, 'clang-tools-extra',
                                       'clang-tidy', 'tool',
                                       'run-clang-tidy.py')

  clang_tidy_binary = GetBinaryPath(clang_build_dir, 'clang-tidy')
  clang_apply_rep_binary = GetBinaryPath(clang_build_dir,
                                         'clang-apply-replacements')

  args = [
      sys.executable,
      run_clang_tidy_script,
      '-quiet',
      '-p',
      out_dir,
      '-clang-tidy-binary',
      clang_tidy_binary,
      '-clang-apply-replacements-binary',
      clang_apply_rep_binary,
  ]

  if checks:
    args.append('-checks={}'.format(checks))

  if header_filter:
    args.append('-header-filter={}'.format(header_filter))

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

  args.append(ninja_target)
  subprocess.check_call(args)


def RunClangTidyDiff(checks, header_filter, auto_fix, clang_src_dir,
                     clang_build_dir, out_dir):
  """Invoke the |clang-tidy-diff.py| script over the diff from stdin."""
  clang_tidy_diff_script = os.path.join(clang_src_dir, 'clang-tools-extra',
                                        'clang-tidy', 'tool',
                                        'clang-tidy-diff.py')

  clang_tidy_binary = GetBinaryPath(clang_build_dir, 'clang-tidy')

  args = [
      clang_tidy_diff_script,
      '-quiet',
      '-p1',
      '-path',
      out_dir,
      '-clang-tidy-binary',
      clang_tidy_binary,
  ]

  if checks:
    args.append('-checks={}'.format(checks))

  if header_filter:
    args.append('-header-filter={}'.format(header_filter))

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

  subprocess.check_call(args)


def main():
  script_name = sys.argv[0]

  parser = argparse.ArgumentParser(
      formatter_class=argparse.RawDescriptionHelpFormatter, epilog=__doc__)
  parser.add_argument(
      '--fetch', action='store_true', help='Fetch and build clang sources')
  parser.add_argument(
      '--build',
      action='store_true',
      help='build clang sources to get clang-tidy')
  parser.add_argument(
      '--diff',
      action='store_true',
      default=False,
      help='read diff from the stdin and check it')
  parser.add_argument(
      '--clang-src-dir',
      type=str,
      help='override llvm and clang checkout location')
  parser.add_argument(
      '--clang-build-dir', type=str, help='override clang build dir location')
  parser.add_argument('--checks', help='passed to clang-tidy')
  parser.add_argument('--header-filter', help='passed to clang-tidy')
  parser.add_argument(
      '--auto-fix',
      action='store_true',
      help='tell clang-tidy to auto-fix errors')
  parser.add_argument('OUT_DIR', help='where we are building Chrome')
  parser.add_argument('NINJA_TARGET', help='ninja target')
  args = parser.parse_args()

  steps = []

  # If the user hasn't provided a clang checkout and build dir, checkout and
  # build clang-tidy where update.py would.
  if not args.clang_src_dir:
    args.clang_src_dir = build_clang_tools_extra.GetCheckoutDir(args.OUT_DIR)
  if not args.clang_build_dir:
    args.clang_build_dir = build_clang_tools_extra.GetBuildDir(args.OUT_DIR)
  elif (args.clang_build_dir and
        not os.path.isfile(GetBinaryPath(args.clang_build_dir, 'clang-tidy'))):
    sys.exit('clang-tidy binary doesn\'t exist at ' +
             GetBinaryPath(args.clang_build_dir, 'clang-tidy'))

  if args.fetch:
    steps.append(
        ('Fetching LLVM sources',
         lambda: build_clang_tools_extra.FetchLLVM(args.clang_src_dir)))

  if args.build:
    steps.append(
        ('Building clang-tidy', lambda: build_clang_tools_extra.BuildTargets(
            args.clang_build_dir, ['clang-tidy', 'clang-apply-replacements'])))

  steps += [('Building ninja target: %s' % args.NINJA_TARGET,
             lambda: BuildNinjaTarget(args.OUT_DIR, args.NINJA_TARGET)),
            ('Generating compilation DB', lambda: GenerateCompDb(args.OUT_DIR))]
  if args.diff:
    steps += [
        ('Running clang-tidy on diff', lambda: RunClangTidyDiff(
            args.checks, args.header_filter, args.auto_fix, args.clang_src_dir,
            args.clang_build_dir, args.OUT_DIR, args.NINJA_TARGET)),
    ]
  else:
    steps += [
        ('Running clang-tidy', lambda: RunClangTidy(
            args.checks, args.header_filter, args.auto_fix, args.clang_src_dir,
            args.clang_build_dir, args.OUT_DIR, args.NINJA_TARGET)),
    ]

  # Run the steps in sequence.
  for i, (msg, step_func) in enumerate(steps):
    # Print progress message
    print '-- %s %s' % (script_name, '-' * (80 - len(script_name) - 4))
    print '-- [%d/%d] %s' % (i + 1, len(steps), msg)
    print 80 * '-'

    step_func()

  return 0


if __name__ == '__main__':
  sys.exit(main())
