# 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/1190269) - 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
