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