#!/usr/bin/env python3
# Copyright 2022 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""check_clang_diags monitors for new diagnostics in LLVM

This looks at projects we care about (currently only clang-tidy, though
hopefully clang in the future, too?) and files bugs whenever a new check or
warning appears. These bugs are intended to keep us up-to-date with new
diagnostics, so we can enable them as they land.
"""

import argparse
import json
import logging
import os
import shutil
import subprocess
import sys
from typing import Dict, List, Tuple

from cros_utils import bugs

_DEFAULT_ASSIGNEE = 'mage'
_DEFAULT_CCS = ['cjdb@google.com']


# FIXME: clang would be cool to check, too? Doesn't seem to have a super stable
# way of listing all warnings, unfortunately.
def _build_llvm(llvm_dir: str, build_dir: str):
  """Builds everything that _collect_available_diagnostics depends on."""
  targets = ['clang-tidy']
  # use `-C $llvm_dir` so the failure is easier to handle if llvm_dir DNE.
  ninja_result = subprocess.run(
      ['ninja', '-C', build_dir] + targets,
      check=False,
  )
  if not ninja_result.returncode:
    return

  # Sometimes the directory doesn't exist, sometimes incremental cmake
  # breaks, sometimes something random happens. Start fresh since that fixes
  # the issue most of the time.
  logging.warning('Initial build failed; trying to build from scratch.')
  shutil.rmtree(build_dir, ignore_errors=True)
  os.makedirs(build_dir)
  subprocess.run(
      [
          'cmake',
          '-G',
          'Ninja',
          '-DCMAKE_BUILD_TYPE=MinSizeRel',
          '-DLLVM_USE_LINKER=lld',
          '-DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra',
          '-DLLVM_TARGETS_TO_BUILD=X86',
          f'{os.path.abspath(llvm_dir)}/llvm',
      ],
      cwd=build_dir,
      check=True,
  )
  subprocess.run(['ninja'] + targets, check=True, cwd=build_dir)


def _collect_available_diagnostics(llvm_dir: str,
                                   build_dir: str) -> Dict[str, List[str]]:
  _build_llvm(llvm_dir, build_dir)

  clang_tidy = os.path.join(os.path.abspath(build_dir), 'bin', 'clang-tidy')
  clang_tidy_checks = subprocess.run(
      [clang_tidy, '-checks=*', '-list-checks'],
      # Use cwd='/' to ensure no .clang-tidy files are picked up. It
      # _shouldn't_ matter, but it's also ~free, so...
      check=True,
      cwd='/',
      stdout=subprocess.PIPE,
      encoding='utf-8',
  )
  clang_tidy_checks_stdout = [
      x.strip() for x in clang_tidy_checks.stdout.strip().splitlines()
  ]

  # The first line should always be this, then each line thereafter is a check
  # name.
  assert clang_tidy_checks_stdout[0] == 'Enabled checks:', (
      clang_tidy_checks_stdout)
  clang_tidy_checks = clang_tidy_checks_stdout[1:]
  assert not any(check.isspace()
                 for check in clang_tidy_checks), (clang_tidy_checks)
  return {'clang-tidy': clang_tidy_checks}


def _process_new_diagnostics(
    old: Dict[str, List[str]], new: Dict[str, List[str]]
) -> Tuple[Dict[str, List[str]], Dict[str, List[str]]]:
  """Determines the set of new diagnostics that we should file bugs for.

    old: The previous state that this function returned as `new_state_file`, or
      `{}`
    new: The diagnostics that we've most recently found. This is a dict in the
      form {tool: [diag]}

    Returns a `new_state_file` to pass into this function as `old` in the
    future, and a dict of diags to file bugs about.
  """
  new_diagnostics = {}
  new_state_file = {}
  for tool, diags in new.items():
    if tool not in old:
      logging.info('New tool with diagnostics: %s; pretending none are new',
                   tool)
      new_state_file[tool] = diags
    else:
      old_diags = set(old[tool])
      newly_added_diags = [x for x in diags if x not in old_diags]
      if newly_added_diags:
        new_diagnostics[tool] = newly_added_diags
      # This specifically tries to make diags sticky: if one is landed, then
      # reverted, then relanded, we ignore the reland. This might not be
      # desirable? I don't know.
      new_state_file[tool] = old[tool] + newly_added_diags

  # Sort things so we have more predictable output.
  for v in new_diagnostics.values():
    v.sort()

  return new_state_file, new_diagnostics


def _file_bugs_for_new_diags(new_diags: Dict[str, List[str]]):
  for tool, diags in sorted(new_diags.items()):
    for diag in diags:
      bugs.CreateNewBug(
          component_id=bugs.WellKnownComponents.CrOSToolchainPublic,
          title=f'Investigate {tool} check `{diag}`',
          body='\n'.join((
              f'It seems that the `{diag}` check was recently added to {tool}.',
              "It's probably good to TAL at whether this check would be good",
              'for us to enable in e.g., platform2, or across ChromeOS.',
          )),
          assignee=_DEFAULT_ASSIGNEE,
          cc=_DEFAULT_CCS,
      )


def main(argv: List[str]):
  logging.basicConfig(
      format='>> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: '
      '%(message)s',
      level=logging.INFO,
  )

  parser = argparse.ArgumentParser(
      description=__doc__,
      formatter_class=argparse.RawDescriptionHelpFormatter,
  )
  parser.add_argument('--llvm_dir',
                      required=True,
                      help='LLVM directory to check. Required.')
  parser.add_argument('--llvm_build_dir',
                      required=True,
                      help='Build directory for LLVM. Required & autocreated.')
  parser.add_argument(
      '--state_file',
      required=True,
      help='State file to use to suppress duplicate complaints. Required.')
  parser.add_argument(
      '--dry_run',
      action='store_true',
      help='Skip filing bugs & writing to the state file; just log '
      'differences.')
  opts = parser.parse_args(argv)

  build_dir = opts.llvm_build_dir
  dry_run = opts.dry_run
  llvm_dir = opts.llvm_dir
  state_file = opts.state_file

  try:
    with open(state_file, encoding='utf-8') as f:
      prior_diagnostics = json.load(f)
  except FileNotFoundError:
    # If the state file didn't exist, just create it without complaining this
    # time.
    prior_diagnostics = {}

  available_diagnostics = _collect_available_diagnostics(llvm_dir, build_dir)
  logging.info('Available diagnostics are %s', available_diagnostics)
  if available_diagnostics == prior_diagnostics:
    logging.info('Current diagnostics are identical to previous ones; quit')
    return

  new_state_file, new_diagnostics = _process_new_diagnostics(
      prior_diagnostics, available_diagnostics)
  logging.info('New diagnostics in existing tool(s): %s', new_diagnostics)

  if dry_run:
    logging.info('Skipping new state file writing and bug filing; dry-run '
                 'mode wins')
  else:
    _file_bugs_for_new_diags(new_diagnostics)
    new_state_file_path = state_file + '.new'
    with open(new_state_file_path, 'w', encoding='utf-8') as f:
      json.dump(new_state_file, f)
    os.rename(new_state_file_path, state_file)


if __name__ == '__main__':
  main(sys.argv[1:])
