# Copyright 2019 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Functions for interacting with llvm-profdata"""

import logging
import multiprocessing
import os
import re
import shutil
import subprocess
import sys

_DIR_SOURCE_ROOT = os.path.normpath(
    os.path.join(os.path.dirname(__file__), '..', '..', '..'))

_JAVA_PATH = os.path.join(_DIR_SOURCE_ROOT, 'third_party', 'jdk', 'current',
                          'bin', 'java')

logging.basicConfig(
    format='[%(asctime)s %(levelname)s] %(message)s', level=logging.DEBUG)


def _call_profdata_tool(profile_input_file_paths,
                        profile_output_file_path,
                        profdata_tool_path,
                        sparse=False,
                        timeout=3600):
  """Calls the llvm-profdata tool.

  Args:
    profile_input_file_paths: A list of relative paths to the files that
        are to be merged.
    profile_output_file_path: The path to the merged file to write.
    profdata_tool_path: The path to the llvm-profdata executable.
    sparse (bool): flag to indicate whether to run llvm-profdata with --sparse.
      Doc: https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-merge
    timeout (int): timeout (sec) for the call to merge profiles. This should
      not take > 1 hr, and so defaults to 3600 seconds.

  Raises:
    CalledProcessError: An error occurred merging profiles.
  """
  # There might be too many files in input and argument limit might be
  # violated, so make the tool read a list of paths from a file.
  output_dir = os.path.dirname(profile_output_file_path)
  # Normalize to POSIX style paths for consistent results.
  input_file = os.path.join(output_dir,
                            'input-profdata-files.txt').replace('\\', '/')
  with open(input_file, 'w') as fd:
    logging.info("List of .profdata files...")
    for file_path in profile_input_file_paths:
      logging.info(file_path)
      fd.write('%s\n' % file_path)
  try:
    subprocess_cmd = [
        profdata_tool_path, 'merge', '-o', profile_output_file_path,
    ]
    if sparse:
      subprocess_cmd += ['-sparse=true',]
    subprocess_cmd.extend(['-f', input_file])
    logging.info('profdata command: %r', subprocess_cmd)

    # Redirecting stderr is required because when error happens, llvm-profdata
    # writes the error output to stderr and our error handling logic relies on
    # that output. stdout=None should print to console.
    # Timeout in seconds, set to 1 hr (60*60)
    p = subprocess.run(subprocess_cmd,
                        capture_output=True,
                        text=True,
                        timeout=timeout,
                        check=True)
    logging.info(p.stdout)
  except subprocess.CalledProcessError as error:
    logging.info('stdout: %s' % error.output)
    logging.error('Failed to merge profiles, return code (%d), error: %r' %
                  (error.returncode, error.stderr))
    raise error
  except subprocess.TimeoutExpired as e:
    logging.info('stdout: %s' % e.output)
    raise e

  logging.info('Profile data is created as: "%r".', profile_output_file_path)


def _get_profile_paths(input_dir,
                       input_extension,
                       input_filename_pattern='.*'):
  """Finds all the profiles in the given directory (recursively)."""
  paths = []
  for dir_path, _sub_dirs, file_names in os.walk(input_dir):
    paths.extend([
        # Normalize to POSIX style paths for consistent results.
        os.path.join(dir_path, fn).replace('\\', '/')
        for fn in file_names
        if fn.endswith(input_extension) and re.search(input_filename_pattern,fn)
    ])
  return paths


def _validate_and_convert_profraws(profraw_files,
                                   profdata_tool_path,
                                   sparse=False):
  """Validates and converts profraws to profdatas.

  For each given .profraw file in the input, this method first validates it by
  trying to convert it to an indexed .profdata file, and if the validation and
  conversion succeeds, the generated .profdata file will be included in the
  output, otherwise, won't.

  This method is mainly used to filter out invalid profraw files.

  Args:
    profraw_files: A list of .profraw paths.
    profdata_tool_path: The path to the llvm-profdata executable.
    sparse (bool): flag to indicate whether to run llvm-profdata with --sparse.
      Doc: https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-merge

  Returns:
    A tuple:
      A list of converted .profdata files of *valid* profraw files.
      A list of *invalid* profraw files.
      A list of profraw files that have counter overflows.
  """
  for profraw_file in profraw_files:
    if not profraw_file.endswith('.profraw'):
      raise RuntimeError('%r is expected to be a .profraw file.' % profraw_file)

  cpu_count = multiprocessing.cpu_count()
  counts = max(10, cpu_count - 5)  # Use 10+ processes, but leave 5 cpu cores.
  if sys.platform == 'win32':
    # TODO(crbug.com/40755900) - we can't use more than 56 child processes on
    # Windows or Python3 may hang.
    counts = min(counts, 56)
  pool = multiprocessing.Pool(counts)
  output_profdata_files = multiprocessing.Manager().list()
  invalid_profraw_files = multiprocessing.Manager().list()
  counter_overflows = multiprocessing.Manager().list()

  results = []
  for profraw_file in profraw_files:
    results.append(pool.apply_async(
      _validate_and_convert_profraw,
      (profraw_file, output_profdata_files, invalid_profraw_files,
        counter_overflows, profdata_tool_path, sparse)))

  pool.close()
  pool.join()

  for x in results:
    x.get()

  # Remove inputs, as they won't be needed and they can be pretty large.
  for input_file in profraw_files:
    os.remove(input_file)

  return list(output_profdata_files), list(invalid_profraw_files), list(
      counter_overflows)


def _validate_and_convert_profraw(profraw_file, output_profdata_files,
                                  invalid_profraw_files, counter_overflows,
                                  profdata_tool_path, sparse=False):
  output_profdata_file = profraw_file.replace('.profraw', '.profdata')
  subprocess_cmd = [
      profdata_tool_path,
      'merge',
      '-o',
      output_profdata_file,
  ]
  if sparse:
    subprocess_cmd.append('--sparse')

  subprocess_cmd.append(profraw_file)
  logging.info('profdata command: %r', subprocess_cmd)

  profile_valid = False
  counter_overflow = False
  validation_output = None

  # 1. Determine if the profile is valid.
  try:
    # Redirecting stderr is required because when error happens, llvm-profdata
    # writes the error output to stderr and our error handling logic relies on
    # that output.
    validation_output = subprocess.check_output(
        subprocess_cmd, stderr=subprocess.STDOUT, encoding = 'UTF-8')
    if 'Counter overflow' in validation_output:
      counter_overflow = True
    else:
      profile_valid = True
  except subprocess.CalledProcessError as error:
    logging.warning('Validating and converting %r to %r failed with output: %r',
                    profraw_file, output_profdata_file, error.output)
    validation_output = error.output

  # 2. Add the profile to the appropriate list(s).
  if profile_valid:
    output_profdata_files.append(output_profdata_file)
  else:
    invalid_profraw_files.append(profraw_file)
    if counter_overflow:
      counter_overflows.append(profraw_file)

  # 3. Log appropriate message
  if not profile_valid:
    template = 'Bad profile: %r, output: %r'
    if counter_overflow:
      template = 'Counter overflow: %r, output: %r'
    logging.warning(template, profraw_file, validation_output)

    # 4. Delete profdata for invalid profiles if present.
    if os.path.exists(output_profdata_file):
      # The output file may be created before llvm-profdata determines the
      # input is invalid. Delete it so that it does not leak and affect other
      # merge scripts.
      os.remove(output_profdata_file)

def merge_java_exec_files(input_dir, output_path, jacococli_path):
  """Merges generated .exec files to output_path.

  Args:
    input_dir (str): The path to traverse to find input files.
    output_path (str): Where to write the merged .exec file.
    jacococli_path: The path to jacococli.jar.

  Raises:
    CalledProcessError: merge command failed.
  """
  exec_input_file_paths = _get_profile_paths(input_dir, '.exec')
  if not exec_input_file_paths:
    logging.info('No exec file found under %s', input_dir)
    return

  cmd = [_JAVA_PATH, '-jar', jacococli_path, 'merge']
  cmd.extend(exec_input_file_paths)
  cmd.extend(['--destfile', output_path])
  subprocess.check_call(cmd, stderr=subprocess.STDOUT)


def merge_profiles(input_dir,
                   output_file,
                   input_extension,
                   profdata_tool_path,
                   input_filename_pattern='.*',
                   sparse=False,
                   skip_validation=False,
                   merge_timeout=3600):
  """Merges the profiles produced by the shards using llvm-profdata.

  Args:
    input_dir (str): The path to traverse to find input profiles.
    output_file (str): Where to write the merged profile.
    input_extension (str): File extension to look for in the input_dir.
        e.g. '.profdata' or '.profraw'
    profdata_tool_path: The path to the llvm-profdata executable.
    input_filename_pattern (str): The regex pattern of input filename. Should be
        a valid regex pattern if present.
    sparse (bool): flag to indicate whether to run llvm-profdata with --sparse.
      Doc: https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-merge
    skip_validation (bool): flag to skip the _validate_and_convert_profraws
        invocation. only applicable when input_extension is .profraw.
    merge_timeout (int): timeout (sec) for the call to merge profiles. This
      should not take > 1 hr, and so defaults to 3600 seconds.

  Returns:
    The list of profiles that had to be excluded to get the merge to
    succeed and a list of profiles that had a counter overflow.
  """
  profile_input_file_paths = _get_profile_paths(input_dir,
                                                input_extension,
                                                input_filename_pattern)
  invalid_profraw_files = []
  counter_overflows = []

  if skip_validation:
    logging.warning('--skip-validation has been enabled. Skipping conversion '
                    'to ensure that profiles are valid.')

  if input_extension == '.profraw' and not skip_validation:
    profile_input_file_paths, invalid_profraw_files, counter_overflows = (
        _validate_and_convert_profraws(profile_input_file_paths,
                                       profdata_tool_path,
                                       sparse=sparse))
    logging.info((
        'List of invalid .profraw files that failed to validate and convert: %r'
    ), invalid_profraw_files)

    if counter_overflows:
      logging.warning('There were %d profiles with counter overflows',
                      len(counter_overflows))

  # The list of input files could be empty in the following scenarios:
  # 1. The test target is pure Python scripts test which doesn't execute any
  #    C/C++ binaries, such as devtools_type_check.
  # 2. The test target executes binary and does dumps coverage profile data
  #    files, however, all of them turned out to be invalid.
  if not profile_input_file_paths:
    logging.info('There is no valid profraw/profdata files to merge, skip '
                 'invoking profdata tools.')
    return invalid_profraw_files, counter_overflows

  _call_profdata_tool(
      profile_input_file_paths=profile_input_file_paths,
      profile_output_file_path=output_file,
      profdata_tool_path=profdata_tool_path,
      sparse=sparse,
      timeout=merge_timeout)

  # Remove inputs when merging profraws as they won't be needed and they can be
  # pretty large. If the inputs are profdata files, do not remove them as they
  # might be used again for multiple test types coverage.
  if input_extension == '.profraw':
    for input_file in profile_input_file_paths:
      os.remove(input_file)

  return invalid_profraw_files, counter_overflows

# We want to retry shards that contain one or more profiles that cannot be
# merged (typically due to corruption described in crbug.com/937521).
def get_shards_to_retry(bad_profiles):
  bad_shard_ids = set()

  def is_task_id(s):
    # Swarming task ids are 16 hex chars. The pythonic way to validate this is
    # to cast to int and catch a value error.
    try:
      assert len(s) == 16, 'Swarming task IDs are expected be of length 16'
      _int_id = int(s, 16)
      return True
    except (AssertionError, ValueError):
      return False

  for profile in bad_profiles:
    # E.g. /b/s/w/ir/tmp/t/tmpSvBRii/44b643576cf39f10/profraw/default-1.profraw
    _base_path, task_id, _profraw, _filename = os.path.normpath(profile).rsplit(
        os.path.sep, 3)
    # Since we are getting a task_id from a file path, which is less than ideal,
    # do some checking to at least verify that the snippet looks like a valid
    # task id.
    assert is_task_id(task_id)
    bad_shard_ids.add(task_id)
  return bad_shard_ids
