#!/usr/bin/env python3
# Copyright 2026 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""CodeCoverageInstaller: Verifies and installs code coverage dependencies.

Automates the verification of:
1. Chromium checkout.
2. LLVM coverage tools (llvm-cov, llvm-profdata).
3. Recipes code (chromium/tools/build).
4. Service code (infra/infra).
"""

import argparse
import os
import pathlib
import subprocess
import sys
import textwrap

SRC_ROOT = pathlib.Path(__file__).resolve().parents[2]


def print_indented(text, level=1, file=None):
  """Prints multi-line text with indentation.

  Args:
      text: The string message to print.
      level: Number of indentation levels (2 spaces per level).
      file: Optional output file stream (defaults to sys.stdout).
  """
  if file is None:
    file = sys.stdout
  indent = '  ' * level
  for line in text.splitlines():
    print(f"{indent}{line}", file=file)


def run_command(args, cwd=None):
  """Executes a subprocess command and prints captured output.

  Args:
      args: Command argument list to run.
      cwd: Optional working directory path for execution.

  Returns:
      The integer return code of the subprocess execution.
  """
  result = subprocess.run(
      args,
      stdout=subprocess.PIPE,
      stderr=subprocess.STDOUT,
      text=True,
      cwd=cwd,
      check=False,
  )
  if result.stdout:
    print_indented(result.stdout, level=2)
  return result.returncode


def verify_chromium_checkout(src_root):
  """Confirms that a valid Chromium checkout exists on disk.

  Args:
      src_root: Path to the Chromium source repository root directory.

  Returns:
      True if DEPS file is found indicating a valid checkout, False otherwise.
  """
  print('Verifying Chromium checkout... ', end='', flush=True)
  try:
    deps_path = src_root / 'DEPS'
    if deps_path.exists():
      print('OK')
      return True
    print('FAIL')
    print_indented(
        'Error: Could not find DEPS file. Not a valid Chromium checkout.',
        file=sys.stderr)
  except Exception as e:
    print('FAIL')
    print_indented(f'Error verifying checkout: {e}', file=sys.stderr)
  return False


def verify_llvm_tools(src_root):
  """Confirms that LLVM coverage binaries are installed.

  Args:
      src_root: Path to the Chromium source repository root directory.

  Returns:
      True if llvm-cov and llvm-profdata binaries exist, False otherwise.
  """
  print('Verifying LLVM coverage tools... ', end='', flush=True)
  try:
    llvm_bin_dir = (src_root / 'third_party' / 'llvm-build' /
                    'Release+Asserts' / 'bin')
    llvm_cov = llvm_bin_dir / 'llvm-cov'
    llvm_profdata = llvm_bin_dir / 'llvm-profdata'

    if llvm_cov.exists() and llvm_profdata.exists():
      print('OK')
      return True

    print('FAIL')
    print_indented(textwrap.dedent("""\
            Error: LLVM coverage tools (llvm-cov, llvm-profdata) are missing.
            To install them, add the following to your .gclient configuration:
              "custom_vars": {
                "checkout_clang_coverage_tools": True,
              }
            And then run: gclient runhooks"""),
                   file=sys.stderr)
  except Exception as e:
    print('FAIL')
    print_indented(f'Error verifying LLVM tools: {e}', file=sys.stderr)
  return False


def verify_recipes(infra_dir):
  """Confirms that the code coverage recipes codebase exists.

  Args:
      infra_dir: Path to the root chrome infra directory.

  Returns:
      True if the code_coverage recipe module directory exists, False otherwise.
  """
  print('Verifying code coverage recipe code... ', end='', flush=True)
  recipe_module_path = (infra_dir / 'build' / 'recipes' / 'recipe_modules' /
                        'code_coverage')
  if recipe_module_path.exists():
    print('OK')
    return True
  print('FAIL')
  return False


def verify_service(infra_dir):
  """Confirms that the code coverage FindIt service codebase exists.

  Args:
      infra_dir: Path to the root chrome infra directory.

  Returns:
      True if the findit service directory exists, False otherwise.
  """
  print('Verifying code coverage service code... ', end='', flush=True)
  service_path = infra_dir / 'infra' / 'appengine' / 'findit'
  if service_path.exists():
    print('OK')
    return True
  print('FAIL')
  return False


def setup_infra(infra_dir):
  """Sets up or syncs the infra_superproject repository checkout.

  Args:
      infra_dir: Target directory path where chrome infra is checked out.

  Returns:
      True if gclient sync or fetch completed successfully, False otherwise.
  """
  print_indented(f'Setting up infra_superproject in {infra_dir}...')
  if not infra_dir.exists():
    infra_dir.mkdir(parents=True)

  gclient_file = infra_dir / '.gclient'
  if gclient_file.exists():
    print_indented(
        'Existing gclient configuration found. Running gclient sync...')
    code = run_command(['gclient', 'sync'], cwd=infra_dir)
    if code == 0:
      print_indented('gclient sync completed successfully.')
      return True
    print_indented(f'Error: gclient sync failed with exit code {code}.',
                   file=sys.stderr)
  else:
    print_indented('Running fetch infra_superproject...')
    code = run_command(['fetch', 'infra_superproject'], cwd=infra_dir)
    if code == 0:
      print_indented('fetch infra_superproject completed successfully.')
      return True
    print_indented(
        f'Error: fetch infra_superproject failed with exit code {code}.',
        file=sys.stderr)
  return False


def verify_gemini_md(src_root):
  """Confirms global code coverage prompt template is imported in GEMINI.md.

  Args:
      src_root: Path to the Chromium source repository root directory.

  Returns:
      True if GEMINI.md was successfully verified or updated, False on error.
  """
  print(
      'Verifying global coverage agent rules in GEMINI.md... ',
      end='',
      flush=True,
  )
  gemini_md = src_root / 'GEMINI.md'
  target_line = '@agents/prompts/templates/code_coverage.md'
  try:
    if gemini_md.exists():
      content = gemini_md.read_text(encoding='utf-8')
      if target_line in content:
        print('OK')
        return True
      with gemini_md.open('a', encoding='utf-8') as f:
        if not content.endswith('\n') and content:
          f.write('\n')
        f.write(f'{target_line}\n')
      print('OK (Appended)')
      return True
    gemini_md.write_text(f'{target_line}\n', encoding='utf-8')
    print('OK (Created)')
    return True
  except Exception as e:
    print('FAIL')
    print_indented(f'Error updating GEMINI.md: {e}', file=sys.stderr)
    return False


def main():
  """Parses command line arguments and runs all verification steps."""
  parser = argparse.ArgumentParser(
      description=
      'Verifies and initializes Code Coverage development environment.')
  parser.add_argument(
      '--infra-dir',
      required=True,
      type=pathlib.Path,
      help='Path to the directory containing (or to checkout) chrome infra '
      'repositories.')
  args = parser.parse_args()
  infra_dir = args.infra_dir.resolve()

  if not verify_chromium_checkout(SRC_ROOT):
    sys.exit(1)

  if not verify_llvm_tools(SRC_ROOT):
    sys.exit(1)

  recipes_ok = verify_recipes(infra_dir)
  service_ok = verify_service(infra_dir)

  if not (recipes_ok and service_ok):
    if not setup_infra(infra_dir):
      sys.exit(1)
    # Re-verify
    if not verify_recipes(infra_dir) or not verify_service(infra_dir):
      print_indented('Error: Verification failed after setup.', file=sys.stderr)
      sys.exit(1)

  if not verify_gemini_md(SRC_ROOT):
    print_indented(
        'Error: Could not verify or initialize GEMINI.md configuration.',
        file=sys.stderr)
    sys.exit(1)

  print('\nCode Coverage environment successfully verified and initialized')


if __name__ == '__main__':
  main()
