#!/usr/bin/python
# Copyright 2017 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.
"""This script helps to generate code coverage report.

  It uses Clang Source-based Code Coverage -
  https://clang.llvm.org/docs/SourceBasedCodeCoverage.html

  In order to generate code coverage report, you need to first add
  "use_clang_coverage=true" and "is_component_build=false" GN flags to args.gn
  file in your build output directory (e.g. out/coverage).

  Example usage:

  gn gen out/coverage --args='use_clang_coverage=true is_component_build=false'
  gclient runhooks
  python tools/code_coverage/coverage.py crypto_unittests url_unittests \\
      -b out/coverage -o out/report -c 'out/coverage/crypto_unittests' \\
      -c 'out/coverage/url_unittests --gtest_filter=URLParser.PathURL' \\
      -f url/ -f crypto/

  The command above builds crypto_unittests and url_unittests targets and then
  runs them with specified command line arguments. For url_unittests, it only
  runs the test URLParser.PathURL. The coverage report is filtered to include
  only files and sub-directories under url/ and crypto/ directories.

  If you want to run tests that try to draw to the screen but don't have a
  display connected, you can run tests in headless mode with xvfb.

  Sample flow for running a test target with xvfb (e.g. unit_tests):

  python tools/code_coverage/coverage.py unit_tests -b out/coverage \\
      -o out/report -c 'python testing/xvfb.py out/coverage/unit_tests'

  If you are building a fuzz target, you need to add "use_libfuzzer=true" GN
  flag as well.

  Sample workflow for a fuzz target (e.g. pdfium_fuzzer):

  python tools/code_coverage/coverage.py pdfium_fuzzer \\
      -b out/coverage -o out/report \\
      -c 'out/coverage/pdfium_fuzzer -runs=<runs> <corpus_dir>' \\
      -f third_party/pdfium

  where:
    <corpus_dir> - directory containing samples files for this format.
    <runs> - number of times to fuzz target function. Should be 0 when you just
             want to see the coverage on corpus and don't want to fuzz at all.

  For more options, please refer to tools/code_coverage/coverage.py -h.

  For an overview of how code coverage works in Chromium, please refer to
  https://chromium.googlesource.com/chromium/src/+/master/docs/code_coverage.md
"""

from __future__ import print_function

import sys

import argparse
import json
import logging
import os
import re
import shlex
import shutil
import subprocess
import urllib2

sys.path.append(
    os.path.join(
        os.path.dirname(__file__), os.path.pardir, os.path.pardir, 'tools',
        'clang', 'scripts'))
import update as clang_update

sys.path.append(
    os.path.join(
        os.path.dirname(__file__), os.path.pardir, os.path.pardir,
        'third_party'))
import jinja2
from collections import defaultdict

# Absolute path to the root of the checkout.
SRC_ROOT_PATH = os.path.abspath(
    os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir))

# Absolute path to the code coverage tools binary.
LLVM_BUILD_DIR = clang_update.LLVM_BUILD_DIR
LLVM_BIN_DIR = os.path.join(LLVM_BUILD_DIR, 'bin')
LLVM_COV_PATH = os.path.join(LLVM_BIN_DIR, 'llvm-cov')
LLVM_PROFDATA_PATH = os.path.join(LLVM_BIN_DIR, 'llvm-profdata')

# Build directory, the value is parsed from command line arguments.
BUILD_DIR = None

# Output directory for generated artifacts, the value is parsed from command
# line arguemnts.
OUTPUT_DIR = None

# Default number of jobs used to build when goma is configured and enabled.
DEFAULT_GOMA_JOBS = 100

# Name of the file extension for profraw data files.
PROFRAW_FILE_EXTENSION = 'profraw'

# Name of the final profdata file, and this file needs to be passed to
# "llvm-cov" command in order to call "llvm-cov show" to inspect the
# line-by-line coverage of specific files.
PROFDATA_FILE_NAME = os.extsep.join(['coverage', 'profdata'])

# Name of the file with summary information generated by llvm-cov export.
SUMMARY_FILE_NAME = os.extsep.join(['summary', 'json'])

# Build arg required for generating code coverage data.
CLANG_COVERAGE_BUILD_ARG = 'use_clang_coverage'

# The default name of the html coverage report for a directory.
DIRECTORY_COVERAGE_HTML_REPORT_NAME = os.extsep.join(['report', 'html'])

# Name of the html index files for different views.
COMPONENT_VIEW_INDEX_FILE = os.extsep.join(['component_view_index', 'html'])
DIRECTORY_VIEW_INDEX_FILE = os.extsep.join(['directory_view_index', 'html'])
FILE_VIEW_INDEX_FILE = os.extsep.join(['file_view_index', 'html'])
INDEX_HTML_FILE = os.extsep.join(['index', 'html'])

LOGS_DIR_NAME = 'logs'

# Used to extract a mapping between directories and components.
COMPONENT_MAPPING_URL = (
    'https://storage.googleapis.com/chromium-owners/component_map.json')

# Caches the results returned by _GetBuildArgs, don't use this variable
# directly, call _GetBuildArgs instead.
_BUILD_ARGS = None

# Retry failed merges.
MERGE_RETRIES = 3

# Message to guide user to file a bug when everything else fails.
FILE_BUG_MESSAGE = (
    'If it persists, please file a bug with the command you used, git revision '
    'and args.gn config here: '
    'https://bugs.chromium.org/p/chromium/issues/entry?'
    'components=Tools%3ECodeCoverage')


class _CoverageSummary(object):
  """Encapsulates coverage summary representation."""

  def __init__(self,
               regions_total=0,
               regions_covered=0,
               functions_total=0,
               functions_covered=0,
               lines_total=0,
               lines_covered=0):
    """Initializes _CoverageSummary object."""
    self._summary = {
        'regions': {
            'total': regions_total,
            'covered': regions_covered
        },
        'functions': {
            'total': functions_total,
            'covered': functions_covered
        },
        'lines': {
            'total': lines_total,
            'covered': lines_covered
        }
    }

  def Get(self):
    """Returns summary as a dictionary."""
    return self._summary

  def AddSummary(self, other_summary):
    """Adds another summary to this one element-wise."""
    for feature in self._summary:
      self._summary[feature]['total'] += other_summary.Get()[feature]['total']
      self._summary[feature]['covered'] += other_summary.Get()[feature][
          'covered']


class _CoverageReportHtmlGenerator(object):
  """Encapsulates coverage html report generation.

  The generated html has a table that contains links to other coverage reports.
  """

  def __init__(self, output_path, table_entry_type):
    """Initializes _CoverageReportHtmlGenerator object.

    Args:
      output_path: Path to the html report that will be generated.
      table_entry_type: Type of the table entries to be displayed in the table
                        header. For example: 'Path', 'Component'.
    """
    css_file_name = os.extsep.join(['style', 'css'])
    css_absolute_path = os.path.join(OUTPUT_DIR, css_file_name)
    assert os.path.exists(css_absolute_path), (
        'css file doesn\'t exit. Please make sure "llvm-cov show -format=html" '
        'is called first, and the css file is generated at: "%s".' %
        css_absolute_path)

    self._css_absolute_path = css_absolute_path
    self._output_path = output_path
    self._table_entry_type = table_entry_type

    self._table_entries = []
    self._total_entry = {}

    source_dir = os.path.dirname(os.path.realpath(__file__))
    template_dir = os.path.join(source_dir, 'html_templates')

    jinja_env = jinja2.Environment(
        loader=jinja2.FileSystemLoader(template_dir), trim_blocks=True)
    self._header_template = jinja_env.get_template('header.html')
    self._table_template = jinja_env.get_template('table.html')
    self._footer_template = jinja_env.get_template('footer.html')

    self._style_overrides = open(
        os.path.join(source_dir, 'static', 'css', 'style.css')).read()

  def AddLinkToAnotherReport(self, html_report_path, name, summary):
    """Adds a link to another html report in this report.

    The link to be added is assumed to be an entry in this directory.
    """
    # Use relative paths instead of absolute paths to make the generated reports
    # portable.
    html_report_relative_path = _GetRelativePathToDirectoryOfFile(
        html_report_path, self._output_path)

    table_entry = self._CreateTableEntryFromCoverageSummary(
        summary, html_report_relative_path, name,
        os.path.basename(html_report_path) ==
        DIRECTORY_COVERAGE_HTML_REPORT_NAME)
    self._table_entries.append(table_entry)

  def CreateTotalsEntry(self, summary):
    """Creates an entry corresponds to the 'Totals' row in the html report."""
    self._total_entry = self._CreateTableEntryFromCoverageSummary(summary)

  def _CreateTableEntryFromCoverageSummary(self,
                                           summary,
                                           href=None,
                                           name=None,
                                           is_dir=None):
    """Creates an entry to display in the html report."""
    assert (href is None and name is None and is_dir is None) or (
        href is not None and name is not None and is_dir is not None), (
            'The only scenario when href or name or is_dir can be None is when '
            'creating an entry for the Totals row, and in that case, all three '
            'attributes must be None.')

    entry = {}
    if href is not None:
      entry['href'] = href
    if name is not None:
      entry['name'] = name
    if is_dir is not None:
      entry['is_dir'] = is_dir

    summary_dict = summary.Get()
    for feature in summary_dict:
      if summary_dict[feature]['total'] == 0:
        percentage = 0.0
      else:
        percentage = float(summary_dict[feature]
                           ['covered']) / summary_dict[feature]['total'] * 100

      color_class = self._GetColorClass(percentage)
      entry[feature] = {
          'total': summary_dict[feature]['total'],
          'covered': summary_dict[feature]['covered'],
          'percentage': '{:6.2f}'.format(percentage),
          'color_class': color_class
      }

    return entry

  def _GetColorClass(self, percentage):
    """Returns the css color class based on coverage percentage."""
    if percentage >= 0 and percentage < 80:
      return 'red'
    if percentage >= 80 and percentage < 100:
      return 'yellow'
    if percentage == 100:
      return 'green'

    assert False, 'Invalid coverage percentage: "%d".' % percentage

  def WriteHtmlCoverageReport(self, no_file_view):
    """Writes html coverage report.

    In the report, sub-directories are displayed before files and within each
    category, entries are sorted alphabetically.
    """

    def EntryCmp(left, right):
      """Compare function for table entries."""
      if left['is_dir'] != right['is_dir']:
        return -1 if left['is_dir'] == True else 1

      return -1 if left['name'] < right['name'] else 1

    self._table_entries = sorted(self._table_entries, cmp=EntryCmp)

    css_path = os.path.join(OUTPUT_DIR, os.extsep.join(['style', 'css']))

    directory_view_path = _GetDirectoryViewPath()
    directory_view_href = _GetRelativePathToDirectoryOfFile(
        directory_view_path, self._output_path)
    component_view_path = _GetComponentViewPath()
    component_view_href = _GetRelativePathToDirectoryOfFile(
        component_view_path, self._output_path)

    # File view is optional in the report.
    file_view_href = None
    if not no_file_view:
      file_view_path = _GetFileViewPath()
      file_view_href = _GetRelativePathToDirectoryOfFile(
          file_view_path, self._output_path)

    html_header = self._header_template.render(
        css_path=_GetRelativePathToDirectoryOfFile(css_path, self._output_path),
        directory_view_href=directory_view_href,
        component_view_href=component_view_href,
        file_view_href=file_view_href,
        style_overrides=self._style_overrides)

    html_table = self._table_template.render(
        entries=self._table_entries,
        total_entry=self._total_entry,
        table_entry_type=self._table_entry_type)
    html_footer = self._footer_template.render()

    with open(self._output_path, 'w') as html_file:
      html_file.write(html_header + html_table + html_footer)


def _ConfigureLogging(args):
  """Configures logging settings for later use."""
  log_level = logging.DEBUG if args.verbose else logging.INFO
  log_format = '[%(asctime)s %(levelname)s] %(message)s'
  log_file = args.log_file if args.log_file else None
  logging.basicConfig(filename=log_file, level=log_level, format=log_format)


def _GetSharedLibraries(binary_paths):
  """Returns list of shared libraries used by specified binaries."""
  logging.info('Finding shared libraries for targets (if any).')
  shared_libraries = []
  cmd = []
  shared_library_re = None

  if sys.platform.startswith('linux'):
    cmd.extend(['ldd'])
    shared_library_re = re.compile(r'.*\.so\s=>\s(.*' + BUILD_DIR +
                                   r'.*\.so)\s.*')
  elif sys.platform.startswith('darwin'):
    cmd.extend(['otool', '-L'])
    shared_library_re = re.compile(r'\s+(@rpath/.*\.dylib)\s.*')
  else:
    assert False, 'Cannot detect shared libraries used by the given targets.'

  assert shared_library_re is not None

  cmd.extend(binary_paths)
  output = subprocess.check_output(cmd)

  for line in output.splitlines():
    m = shared_library_re.match(line)
    if not m:
      continue

    shared_library_path = m.group(1)
    if sys.platform.startswith('darwin'):
      # otool outputs "@rpath" macro instead of the dirname of the given binary.
      shared_library_path = shared_library_path.replace('@rpath', BUILD_DIR)

    if shared_library_path in shared_libraries:
      continue

    assert os.path.exists(shared_library_path), ('Shared library "%s" used by '
                                                 'the given target(s) does not '
                                                 'exist.' % shared_library_path)
    with open(shared_library_path) as f:
      data = f.read()

    # Do not add non-instrumented libraries. Otherwise, llvm-cov errors outs.
    if '__llvm_cov' in data:
      shared_libraries.append(shared_library_path)

  logging.debug('Found shared libraries (%d): %s.', len(shared_libraries),
                shared_libraries)
  logging.info('Finished finding shared libraries for targets.')
  return shared_libraries


def _GetHostPlatform():
  """Returns the host platform.

  This is separate from the target platform/os that coverage is running for.
  """
  if sys.platform == 'win32' or sys.platform == 'cygwin':
    return 'win'
  if sys.platform.startswith('linux'):
    return 'linux'
  else:
    assert sys.platform == 'darwin'
    return 'mac'


def _GetPathWithLLVMSymbolizerDir():
  """Add llvm-symbolizer directory to path for symbolized stacks."""
  path = os.getenv('PATH')
  dirs = path.split(os.pathsep)
  if LLVM_BIN_DIR in dirs:
    return path

  return path + os.pathsep + LLVM_BIN_DIR


def _GetTargetOS():
  """Returns the target os specified in args.gn file.

  Returns an empty string is target_os is not specified.
  """
  build_args = _GetBuildArgs()
  return build_args['target_os'] if 'target_os' in build_args else ''


def _IsIOS():
  """Returns true if the target_os specified in args.gn file is ios"""
  return _GetTargetOS() == 'ios'


# TODO(crbug.com/759794): remove this function once tools get included to
# Clang bundle:
# https://chromium-review.googlesource.com/c/chromium/src/+/688221
def DownloadCoverageToolsIfNeeded():
  """Temporary solution to download llvm-profdata and llvm-cov tools."""

  def _GetRevisionFromStampFile(stamp_file_path):
    """Returns a pair of revision number by reading the build stamp file.

    Args:
      stamp_file_path: A path the build stamp file created by
                       tools/clang/scripts/update.py.
    Returns:
      A pair of integers represeting the main and sub revision respectively.
    """
    if not os.path.exists(stamp_file_path):
      return 0, 0

    with open(stamp_file_path) as stamp_file:
      stamp_file_line = stamp_file.readline()
      if ',' in stamp_file_line:
        package_version = stamp_file_line.rstrip().split(',')[0]
      else:
        package_version = stamp_file_line.rstrip()

      clang_revision_str, clang_sub_revision_str = package_version.split('-')
      return int(clang_revision_str), int(clang_sub_revision_str)

  host_platform = _GetHostPlatform()
  clang_revision, clang_sub_revision = _GetRevisionFromStampFile(
      clang_update.STAMP_FILE)

  coverage_revision_stamp_file = os.path.join(
      os.path.dirname(clang_update.STAMP_FILE), 'cr_coverage_revision')
  coverage_revision, coverage_sub_revision = _GetRevisionFromStampFile(
      coverage_revision_stamp_file)

  has_coverage_tools = (
      os.path.exists(LLVM_COV_PATH) and os.path.exists(LLVM_PROFDATA_PATH))

  if (has_coverage_tools and coverage_revision == clang_revision and
      coverage_sub_revision == clang_sub_revision):
    # LLVM coverage tools are up to date, bail out.
    return

  package_version = '%d-%d' % (clang_revision, clang_sub_revision)
  coverage_tools_file = 'llvm-code-coverage-%s.tgz' % package_version

  # The code bellow follows the code from tools/clang/scripts/update.py.
  if host_platform == 'mac':
    coverage_tools_url = clang_update.CDS_URL + '/Mac/' + coverage_tools_file
  elif host_platform == 'linux':
    coverage_tools_url = (
        clang_update.CDS_URL + '/Linux_x64/' + coverage_tools_file)
  else:
    assert host_platform == 'win'
    coverage_tools_url = (clang_update.CDS_URL + '/Win/' + coverage_tools_file)

  try:
    clang_update.DownloadAndUnpack(coverage_tools_url,
                                   clang_update.LLVM_BUILD_DIR)
    with open(coverage_revision_stamp_file, 'w') as file_handle:
      file_handle.write('%s,%s' % (package_version, host_platform))
      file_handle.write('\n')
  except urllib2.URLError:
    raise Exception(
        'Failed to download coverage tools: %s.' % coverage_tools_url)


def _GeneratePerFileLineByLineCoverageInHtml(binary_paths, profdata_file_path,
                                             filters, ignore_filename_regex):
  """Generates per file line-by-line coverage in html using 'llvm-cov show'.

  For a file with absolute path /a/b/x.cc, a html report is generated as:
  OUTPUT_DIR/coverage/a/b/x.cc.html. An index html file is also generated as:
  OUTPUT_DIR/index.html.

  Args:
    binary_paths: A list of paths to the instrumented binaries.
    profdata_file_path: A path to the profdata file.
    filters: A list of directories and files to get coverage for.
  """
  # llvm-cov show [options] -instr-profile PROFILE BIN [-object BIN,...]
  # [[-object BIN]] [SOURCES]
  # NOTE: For object files, the first one is specified as a positional argument,
  # and the rest are specified as keyword argument.
  logging.debug('Generating per file line by line coverage reports using '
                '"llvm-cov show" command.')
  subprocess_cmd = [
      LLVM_COV_PATH, 'show', '-format=html',
      '-output-dir={}'.format(OUTPUT_DIR),
      '-instr-profile={}'.format(profdata_file_path), binary_paths[0]
  ]
  subprocess_cmd.extend(
      ['-object=' + binary_path for binary_path in binary_paths[1:]])
  _AddArchArgumentForIOSIfNeeded(subprocess_cmd, len(binary_paths))
  subprocess_cmd.extend(filters)
  if ignore_filename_regex:
    subprocess_cmd.append('-ignore-filename-regex=%s' % ignore_filename_regex)

  subprocess.check_call(subprocess_cmd)

  # llvm-cov creates "coverage" subdir in the output dir. We would like to use
  # the platform name instead, as it simplifies the report dir structure when
  # the same report is generated for different platforms.
  default_report_subdir_path = os.path.join(OUTPUT_DIR, 'coverage')
  platform_report_subdir_path = _GetCoverageReportRootDirPath()
  _MergeTwoDirectories(default_report_subdir_path, platform_report_subdir_path)

  logging.debug('Finished running "llvm-cov show" command.')


def _GenerateFileViewHtmlIndexFile(per_file_coverage_summary):
  """Generates html index file for file view."""
  file_view_index_file_path = _GetFileViewPath()
  logging.debug('Generating file view html index file as: "%s".',
                file_view_index_file_path)
  html_generator = _CoverageReportHtmlGenerator(file_view_index_file_path,
                                                'Path')
  totals_coverage_summary = _CoverageSummary()

  for file_path in per_file_coverage_summary:
    totals_coverage_summary.AddSummary(per_file_coverage_summary[file_path])

    html_generator.AddLinkToAnotherReport(
        _GetCoverageHtmlReportPathForFile(file_path),
        os.path.relpath(file_path, SRC_ROOT_PATH),
        per_file_coverage_summary[file_path])

  html_generator.CreateTotalsEntry(totals_coverage_summary)
  html_generator.WriteHtmlCoverageReport(no_file_view=False)
  logging.debug('Finished generating file view html index file.')


def _CalculatePerDirectoryCoverageSummary(per_file_coverage_summary):
  """Calculates per directory coverage summary."""
  logging.debug('Calculating per-directory coverage summary.')
  per_directory_coverage_summary = defaultdict(lambda: _CoverageSummary())

  for file_path in per_file_coverage_summary:
    summary = per_file_coverage_summary[file_path]
    parent_dir = os.path.dirname(file_path)

    while True:
      per_directory_coverage_summary[parent_dir].AddSummary(summary)

      if parent_dir == SRC_ROOT_PATH:
        break
      parent_dir = os.path.dirname(parent_dir)

  logging.debug('Finished calculating per-directory coverage summary.')
  return per_directory_coverage_summary


def _GeneratePerDirectoryCoverageInHtml(
    per_directory_coverage_summary, per_file_coverage_summary, no_file_view):
  """Generates per directory coverage breakdown in html."""
  logging.debug('Writing per-directory coverage html reports.')
  for dir_path in per_directory_coverage_summary:
    _GenerateCoverageInHtmlForDirectory(dir_path,
                                        per_directory_coverage_summary,
                                        per_file_coverage_summary, no_file_view)

  logging.debug('Finished writing per-directory coverage html reports.')


def _GenerateCoverageInHtmlForDirectory(
    dir_path, per_directory_coverage_summary, per_file_coverage_summary,
    no_file_view):
  """Generates coverage html report for a single directory."""
  html_generator = _CoverageReportHtmlGenerator(
      _GetCoverageHtmlReportPathForDirectory(dir_path), 'Path')

  for entry_name in os.listdir(dir_path):
    entry_path = os.path.normpath(os.path.join(dir_path, entry_name))

    if entry_path in per_file_coverage_summary:
      entry_html_report_path = _GetCoverageHtmlReportPathForFile(entry_path)
      entry_coverage_summary = per_file_coverage_summary[entry_path]
    elif entry_path in per_directory_coverage_summary:
      entry_html_report_path = _GetCoverageHtmlReportPathForDirectory(
          entry_path)
      entry_coverage_summary = per_directory_coverage_summary[entry_path]
    else:
      # Any file without executable lines shouldn't be included into the report.
      # For example, OWNER and README.md files.
      continue

    html_generator.AddLinkToAnotherReport(entry_html_report_path,
                                          os.path.basename(entry_path),
                                          entry_coverage_summary)

  html_generator.CreateTotalsEntry(per_directory_coverage_summary[dir_path])
  html_generator.WriteHtmlCoverageReport(no_file_view)


def _GenerateDirectoryViewHtmlIndexFile():
  """Generates the html index file for directory view.

  Note that the index file is already generated under SRC_ROOT_PATH, so this
  file simply redirects to it, and the reason of this extra layer is for
  structural consistency with other views.
  """
  directory_view_index_file_path = _GetDirectoryViewPath()
  logging.debug('Generating directory view html index file as: "%s".',
                directory_view_index_file_path)
  src_root_html_report_path = _GetCoverageHtmlReportPathForDirectory(
      SRC_ROOT_PATH)
  _WriteRedirectHtmlFile(directory_view_index_file_path,
                         src_root_html_report_path)
  logging.debug('Finished generating directory view html index file.')


def _CalculatePerComponentCoverageSummary(component_to_directories,
                                          per_directory_coverage_summary):
  """Calculates per component coverage summary."""
  logging.debug('Calculating per-component coverage summary.')
  per_component_coverage_summary = defaultdict(lambda: _CoverageSummary())

  for component in component_to_directories:
    for directory in component_to_directories[component]:
      absolute_directory_path = os.path.abspath(directory)
      if absolute_directory_path in per_directory_coverage_summary:
        per_component_coverage_summary[component].AddSummary(
            per_directory_coverage_summary[absolute_directory_path])

  logging.debug('Finished calculating per-component coverage summary.')
  return per_component_coverage_summary


def _ExtractComponentToDirectoriesMapping():
  """Returns a mapping from components to directories."""
  component_mappings = json.load(urllib2.urlopen(COMPONENT_MAPPING_URL))
  directory_to_component = component_mappings['dir-to-component']

  component_to_directories = defaultdict(list)
  for directory in sorted(directory_to_component):
    component = directory_to_component[directory]

    # Check if we already added the parent directory of this directory. If yes,
    # skip this sub-directory to avoid double-counting.
    found_parent_directory = False
    for component_directory in component_to_directories[component]:
      if directory.startswith(component_directory + '/'):
        found_parent_directory = True
        break

    if not found_parent_directory:
      component_to_directories[component].append(directory)

  return component_to_directories


def _GeneratePerComponentCoverageInHtml(
    per_component_coverage_summary, component_to_directories,
    per_directory_coverage_summary, no_file_view):
  """Generates per-component coverage reports in html."""
  logging.debug('Writing per-component coverage html reports.')
  for component in per_component_coverage_summary:
    _GenerateCoverageInHtmlForComponent(
        component, per_component_coverage_summary, component_to_directories,
        per_directory_coverage_summary, no_file_view)

  logging.debug('Finished writing per-component coverage html reports.')


def _GenerateCoverageInHtmlForComponent(
    component_name, per_component_coverage_summary, component_to_directories,
    per_directory_coverage_summary, no_file_view):
  """Generates coverage html report for a component."""
  component_html_report_path = _GetCoverageHtmlReportPathForComponent(
      component_name)
  component_html_report_dir = os.path.dirname(component_html_report_path)
  if not os.path.exists(component_html_report_dir):
    os.makedirs(component_html_report_dir)

  html_generator = _CoverageReportHtmlGenerator(component_html_report_path,
                                                'Path')

  for dir_path in component_to_directories[component_name]:
    dir_absolute_path = os.path.abspath(dir_path)
    if dir_absolute_path not in per_directory_coverage_summary:
      # Any directory without an excercised file shouldn't be included into the
      # report.
      continue

    html_generator.AddLinkToAnotherReport(
        _GetCoverageHtmlReportPathForDirectory(dir_path),
        os.path.relpath(dir_path, SRC_ROOT_PATH),
        per_directory_coverage_summary[dir_absolute_path])

  html_generator.CreateTotalsEntry(
      per_component_coverage_summary[component_name])
  html_generator.WriteHtmlCoverageReport(no_file_view)


def _GenerateComponentViewHtmlIndexFile(per_component_coverage_summary,
                                        no_file_view):
  """Generates the html index file for component view."""
  component_view_index_file_path = _GetComponentViewPath()
  logging.debug('Generating component view html index file as: "%s".',
                component_view_index_file_path)
  html_generator = _CoverageReportHtmlGenerator(component_view_index_file_path,
                                                'Component')
  totals_coverage_summary = _CoverageSummary()

  for component in per_component_coverage_summary:
    totals_coverage_summary.AddSummary(
        per_component_coverage_summary[component])

    html_generator.AddLinkToAnotherReport(
        _GetCoverageHtmlReportPathForComponent(component), component,
        per_component_coverage_summary[component])

  html_generator.CreateTotalsEntry(totals_coverage_summary)
  html_generator.WriteHtmlCoverageReport(no_file_view)
  logging.debug('Finished generating component view html index file.')


def _MergeTwoDirectories(src_path, dst_path):
  """Merge src_path directory into dst_path directory."""
  for filename in os.listdir(src_path):
    dst_path = os.path.join(dst_path, filename)
    if os.path.exists(dst_path):
      shutil.rmtree(dst_path)
    os.rename(os.path.join(src_path, filename), dst_path)
  shutil.rmtree(src_path)


def _OverwriteHtmlReportsIndexFile():
  """Overwrites the root index file to redirect to the default view."""
  html_index_file_path = _GetHtmlIndexPath()
  directory_view_index_file_path = _GetDirectoryViewPath()
  _WriteRedirectHtmlFile(html_index_file_path, directory_view_index_file_path)


def _WriteRedirectHtmlFile(from_html_path, to_html_path):
  """Writes a html file that redirects to another html file."""
  to_html_relative_path = _GetRelativePathToDirectoryOfFile(
      to_html_path, from_html_path)
  content = ("""
    <!DOCTYPE html>
    <html>
      <head>
        <!-- HTML meta refresh URL redirection -->
        <meta http-equiv="refresh" content="0; url=%s">
      </head>
    </html>""" % to_html_relative_path)
  with open(from_html_path, 'w') as f:
    f.write(content)


def _CleanUpOutputDir():
  """Perform a cleanup of the output dir."""
  # Remove the default index.html file produced by llvm-cov.
  index_path = os.path.join(OUTPUT_DIR, INDEX_HTML_FILE)
  if os.path.exists(index_path):
    os.remove(index_path)


def _GetCoverageHtmlReportPathForFile(file_path):
  """Given a file path, returns the corresponding html report path."""
  assert os.path.isfile(file_path), '"%s" is not a file.' % file_path
  html_report_path = os.extsep.join([os.path.abspath(file_path), 'html'])

  # '+' is used instead of os.path.join because both of them are absolute paths
  # and os.path.join ignores the first path.
  # TODO(crbug.com/809150): Think of a generic cross platform fix (Windows).
  return _GetCoverageReportRootDirPath() + html_report_path


def _GetCoverageHtmlReportPathForDirectory(dir_path):
  """Given a directory path, returns the corresponding html report path."""
  assert os.path.isdir(dir_path), '"%s" is not a directory.' % dir_path
  html_report_path = os.path.join(
      os.path.abspath(dir_path), DIRECTORY_COVERAGE_HTML_REPORT_NAME)

  # '+' is used instead of os.path.join because both of them are absolute paths
  # and os.path.join ignores the first path.
  # TODO(crbug.com/809150): Think of a generic cross platform fix (Windows).
  return _GetCoverageReportRootDirPath() + html_report_path


def _GetCoverageHtmlReportPathForComponent(component_name):
  """Given a component, returns the corresponding html report path."""
  component_file_name = component_name.lower().replace('>', '-')
  html_report_name = os.extsep.join([component_file_name, 'html'])
  return os.path.join(_GetCoverageReportRootDirPath(), 'components',
                      html_report_name)


def _GetCoverageReportRootDirPath():
  """The root directory that contains all generated coverage html reports."""
  return os.path.join(OUTPUT_DIR, _GetHostPlatform())


def _GetComponentViewPath():
  """Path to the HTML file for the component view."""
  return os.path.join(_GetCoverageReportRootDirPath(),
                      COMPONENT_VIEW_INDEX_FILE)


def _GetDirectoryViewPath():
  """Path to the HTML file for the directory view."""
  return os.path.join(_GetCoverageReportRootDirPath(),
                      DIRECTORY_VIEW_INDEX_FILE)


def _GetFileViewPath():
  """Path to the HTML file for the file view."""
  return os.path.join(_GetCoverageReportRootDirPath(), FILE_VIEW_INDEX_FILE)


def _GetLogsDirectoryPath():
  """Path to the logs directory."""
  return os.path.join(_GetCoverageReportRootDirPath(), LOGS_DIR_NAME)


def _GetHtmlIndexPath():
  """Path to the main HTML index file."""
  return os.path.join(_GetCoverageReportRootDirPath(), INDEX_HTML_FILE)


def _GetProfdataFilePath():
  """Path to the resulting .profdata file."""
  return os.path.join(_GetCoverageReportRootDirPath(), PROFDATA_FILE_NAME)


def _GetSummaryFilePath():
  """The JSON file that contains coverage summary written by llvm-cov export."""
  return os.path.join(_GetCoverageReportRootDirPath(), SUMMARY_FILE_NAME)


def _CreateCoverageProfileDataForTargets(targets, commands, jobs_count=None):
  """Builds and runs target to generate the coverage profile data.

  Args:
    targets: A list of targets to build with coverage instrumentation.
    commands: A list of commands used to run the targets.
    jobs_count: Number of jobs to run in parallel for building. If None, a
                default value is derived based on CPUs availability.

  Returns:
    A relative path to the generated profdata file.
  """
  _BuildTargets(targets, jobs_count)
  target_profdata_file_paths = _GetTargetProfDataPathsByExecutingCommands(
      targets, commands)
  coverage_profdata_file_path = (
      _CreateCoverageProfileDataFromTargetProfDataFiles(
          target_profdata_file_paths))

  for target_profdata_file_path in target_profdata_file_paths:
    os.remove(target_profdata_file_path)

  return coverage_profdata_file_path


def _BuildTargets(targets, jobs_count):
  """Builds target with Clang coverage instrumentation.

  This function requires current working directory to be the root of checkout.

  Args:
    targets: A list of targets to build with coverage instrumentation.
    jobs_count: Number of jobs to run in parallel for compilation. If None, a
                default value is derived based on CPUs availability.
  """

  def _IsGomaConfigured():
    """Returns True if goma is enabled in the gn build args.

    Returns:
      A boolean indicates whether goma is configured for building or not.
    """
    build_args = _GetBuildArgs()
    return 'use_goma' in build_args and build_args['use_goma'] == 'true'

  logging.info('Building %s.', str(targets))
  if jobs_count is None and _IsGomaConfigured():
    jobs_count = DEFAULT_GOMA_JOBS

  subprocess_cmd = ['ninja', '-C', BUILD_DIR]
  if jobs_count is not None:
    subprocess_cmd.append('-j' + str(jobs_count))

  subprocess_cmd.extend(targets)
  subprocess.check_call(subprocess_cmd)
  logging.debug('Finished building %s.', str(targets))


def _GetTargetProfDataPathsByExecutingCommands(targets, commands):
  """Runs commands and returns the relative paths to the profraw data files.

  Args:
    targets: A list of targets built with coverage instrumentation.
    commands: A list of commands used to run the targets.

  Returns:
    A list of relative paths to the generated profraw data files.
  """
  logging.debug('Executing the test commands.')

  # Remove existing profraw data files.
  for file_or_dir in os.listdir(_GetCoverageReportRootDirPath()):
    if file_or_dir.endswith(PROFRAW_FILE_EXTENSION):
      os.remove(os.path.join(_GetCoverageReportRootDirPath(), file_or_dir))

  # Ensure that logs directory exists.
  if not os.path.exists(_GetLogsDirectoryPath()):
    os.makedirs(_GetLogsDirectoryPath())

  profdata_file_paths = []

  # Run all test targets to generate profraw data files.
  for target, command in zip(targets, commands):
    output_file_name = os.extsep.join([target + '_output', 'log'])
    output_file_path = os.path.join(_GetLogsDirectoryPath(), output_file_name)

    profdata_file_path = None
    for _ in xrange(MERGE_RETRIES):
      logging.info('Running command: "%s", the output is redirected to "%s".',
                   command, output_file_path)

      if _IsIOSCommand(command):
        # On iOS platform, due to lack of write permissions, profraw files are
        # generated outside of the OUTPUT_DIR, and the exact paths are contained
        # in the output of the command execution.
        output = _ExecuteIOSCommand(target, command)
      else:
        # On other platforms, profraw files are generated inside the OUTPUT_DIR.
        output = _ExecuteCommand(target, command)

      with open(output_file_path, 'w') as output_file:
        output_file.write(output)

      profraw_file_paths = []
      if _IsIOS():
        profraw_file_paths = _GetProfrawDataFileByParsingOutput(output)
      else:
        for file_or_dir in os.listdir(_GetCoverageReportRootDirPath()):
          if file_or_dir.endswith(PROFRAW_FILE_EXTENSION):
            profraw_file_paths.append(
                os.path.join(_GetCoverageReportRootDirPath(), file_or_dir))

      assert profraw_file_paths, (
          'Running target "%s" failed to generate any profraw data file, '
          'please make sure the binary exists, is properly instrumented and '
          'does not crash. %s' % (target, FILE_BUG_MESSAGE))

      try:
        profdata_file_path = _CreateTargetProfDataFileFromProfRawFiles(
            target, profraw_file_paths)
        break
      except Exception:
        logging.info('Retrying...')
      finally:
        # Remove profraw files now so that they are not used in next iteration.
        for profraw_file_path in profraw_file_paths:
          os.remove(profraw_file_path)

    assert profdata_file_path, (
        'Failed to merge target "%s" profraw files after %d retries. %s' %
        (target, MERGE_RETRIES, FILE_BUG_MESSAGE))
    profdata_file_paths.append(profdata_file_path)

  logging.debug('Finished executing the test commands.')

  return profdata_file_paths


def _ExecuteCommand(target, command):
  """Runs a single command and generates a profraw data file."""
  # Per Clang "Source-based Code Coverage" doc:
  #
  # "%p" expands out to the process ID. It's not used by this scripts due to:
  # 1) If a target program spawns too many processess, it may exhaust all disk
  #    space available. For example, unit_tests writes thousands of .profraw
  #    files each of size 1GB+.
  # 2) If a target binary uses shared libraries, coverage profile data for them
  #    will be missing, resulting in incomplete coverage reports.
  #
  # "%Nm" expands out to the instrumented binary's signature. When this pattern
  # is specified, the runtime creates a pool of N raw profiles which are used
  # for on-line profile merging. The runtime takes care of selecting a raw
  # profile from the pool, locking it, and updating it before the program exits.
  # N must be between 1 and 9. The merge pool specifier can only occur once per
  # filename pattern.
  #
  # "%1m" is used when tests run in single process, such as fuzz targets.
  #
  # For other cases, "%4m" is chosen as it creates some level of parallelism,
  # but it's not too big to consume too much computing resource or disk space.
  profile_pattern_string = '%1m' if _IsFuzzerTarget(target) else '%4m'
  expected_profraw_file_name = os.extsep.join(
      [target, profile_pattern_string, PROFRAW_FILE_EXTENSION])
  expected_profraw_file_path = os.path.join(_GetCoverageReportRootDirPath(),
                                            expected_profraw_file_name)

  try:
    # Some fuzz targets or tests may write into stderr, redirect it as well.
    output = subprocess.check_output(
        shlex.split(command),
        stderr=subprocess.STDOUT,
        env={
            'LLVM_PROFILE_FILE': expected_profraw_file_path,
            'PATH': _GetPathWithLLVMSymbolizerDir()
        })
  except subprocess.CalledProcessError as e:
    output = e.output
    logging.warning(
        'Command: "%s" exited with non-zero return code. Output:\n%s', command,
        output)

  return output


def _IsFuzzerTarget(target):
  """Returns true if the target is a fuzzer target."""
  build_args = _GetBuildArgs()
  use_libfuzzer = ('use_libfuzzer' in build_args and
                   build_args['use_libfuzzer'] == 'true')
  return use_libfuzzer and target.endswith('_fuzzer')


def _ExecuteIOSCommand(target, command):
  """Runs a single iOS command and generates a profraw data file.

  iOS application doesn't have write access to folders outside of the app, so
  it's impossible to instruct the app to flush the profraw data file to the
  desired location. The profraw data file will be generated somewhere within the
  application's Documents folder, and the full path can be obtained by parsing
  the output.
  """
  assert _IsIOSCommand(command)

  # After running tests, iossim generates a profraw data file, it won't be
  # needed anyway, so dump it into the OUTPUT_DIR to avoid polluting the
  # checkout.
  iossim_profraw_file_path = os.path.join(
      OUTPUT_DIR, os.extsep.join(['iossim', PROFRAW_FILE_EXTENSION]))

  try:
    output = subprocess.check_output(
        shlex.split(command),
        env={
            'LLVM_PROFILE_FILE': iossim_profraw_file_path,
            'PATH': _GetPathWithLLVMSymbolizerDir()
        })
  except subprocess.CalledProcessError as e:
    # iossim emits non-zero return code even if tests run successfully, so
    # ignore the return code.
    output = e.output

  return output


def _GetProfrawDataFileByParsingOutput(output):
  """Returns the path to the profraw data file obtained by parsing the output.

  The output of running the test target has no format, but it is guaranteed to
  have a single line containing the path to the generated profraw data file.
  NOTE: This should only be called when target os is iOS.
  """
  assert _IsIOS()

  output_by_lines = ''.join(output).splitlines()
  profraw_file_pattern = re.compile('.*Coverage data at (.*coverage\.profraw).')

  for line in output_by_lines:
    result = profraw_file_pattern.match(line)
    if result:
      return result.group(1)

  assert False, ('No profraw data file was generated, did you call '
                 'coverage_util::ConfigureCoverageReportPath() in test setup? '
                 'Please refer to base/test/test_support_ios.mm for example.')


def _CreateCoverageProfileDataFromTargetProfDataFiles(profdata_file_paths):
  """Returns a relative path to coverage profdata file by merging target
  profdata files.

  Args:
    profdata_file_paths: A list of relative paths to the profdata data files
                         that are to be merged.

  Returns:
    A relative path to the merged coverage profdata file.

  Raises:
    CalledProcessError: An error occurred merging profdata files.
  """
  logging.info('Creating the coverage profile data file.')
  logging.debug('Merging target profraw files to create target profdata file.')
  profdata_file_path = _GetProfdataFilePath()
  try:
    subprocess_cmd = [
        LLVM_PROFDATA_PATH, 'merge', '-o', profdata_file_path, '-sparse=true'
    ]
    subprocess_cmd.extend(profdata_file_paths)
    subprocess.check_call(subprocess_cmd)
  except subprocess.CalledProcessError as error:
    logging.error(
        'Failed to merge target profdata files to create coverage profdata. %s',
        FILE_BUG_MESSAGE)
    raise error

  logging.debug('Finished merging target profdata files.')
  logging.info('Code coverage profile data is created as: "%s".',
               profdata_file_path)
  return profdata_file_path


def _CreateTargetProfDataFileFromProfRawFiles(target, profraw_file_paths):
  """Returns a relative path to target profdata file by merging target
  profraw files.

  Args:
    profraw_file_paths: A list of relative paths to the profdata data files
                         that are to be merged.

  Returns:
    A relative path to the merged coverage profdata file.

  Raises:
    CalledProcessError: An error occurred merging profdata files.
  """
  logging.info('Creating target profile data file.')
  logging.debug('Merging target profraw files to create target profdata file.')
  profdata_file_path = os.path.join(OUTPUT_DIR, '%s.profdata' % target)

  try:
    subprocess_cmd = [
        LLVM_PROFDATA_PATH, 'merge', '-o', profdata_file_path, '-sparse=true'
    ]
    subprocess_cmd.extend(profraw_file_paths)
    subprocess.check_call(subprocess_cmd)
  except subprocess.CalledProcessError as error:
    logging.error(
        'Failed to merge target profraw files to create target profdata.')
    raise error

  logging.debug('Finished merging target profraw files.')
  logging.info('Target "%s" profile data is created as: "%s".', target,
               profdata_file_path)
  return profdata_file_path


def _GeneratePerFileCoverageSummary(binary_paths, profdata_file_path, filters,
                                    ignore_filename_regex):
  """Generates per file coverage summary using "llvm-cov export" command."""
  # llvm-cov export [options] -instr-profile PROFILE BIN [-object BIN,...]
  # [[-object BIN]] [SOURCES].
  # NOTE: For object files, the first one is specified as a positional argument,
  # and the rest are specified as keyword argument.
  logging.debug('Generating per-file code coverage summary using "llvm-cov '
                'export -summary-only" command.')
  subprocess_cmd = [
      LLVM_COV_PATH, 'export', '-summary-only',
      '-instr-profile=' + profdata_file_path, binary_paths[0]
  ]
  subprocess_cmd.extend(
      ['-object=' + binary_path for binary_path in binary_paths[1:]])
  _AddArchArgumentForIOSIfNeeded(subprocess_cmd, len(binary_paths))
  subprocess_cmd.extend(filters)
  if ignore_filename_regex:
    subprocess_cmd.append('-ignore-filename-regex=%s' % ignore_filename_regex)

  export_output = subprocess.check_output(subprocess_cmd)

  # Write output on the disk to be used by code coverage bot.
  with open(_GetSummaryFilePath(), 'w') as f:
    f.write(export_output)

  json_output = json.loads(export_output)
  assert len(json_output['data']) == 1
  files_coverage_data = json_output['data'][0]['files']

  per_file_coverage_summary = {}
  for file_coverage_data in files_coverage_data:
    file_path = file_coverage_data['filename']
    assert file_path.startswith(SRC_ROOT_PATH + os.sep), (
        'File path "%s" in coverage summary is outside source checkout.' %
        file_path)

    summary = file_coverage_data['summary']
    if summary['lines']['count'] == 0:
      continue

    per_file_coverage_summary[file_path] = _CoverageSummary(
        regions_total=summary['regions']['count'],
        regions_covered=summary['regions']['covered'],
        functions_total=summary['functions']['count'],
        functions_covered=summary['functions']['covered'],
        lines_total=summary['lines']['count'],
        lines_covered=summary['lines']['covered'])

  logging.debug('Finished generating per-file code coverage summary.')
  return per_file_coverage_summary


def _AddArchArgumentForIOSIfNeeded(cmd_list, num_archs):
  """Appends -arch arguments to the command list if it's ios platform.

  iOS binaries are universal binaries, and require specifying the architecture
  to use, and one architecture needs to be specified for each binary.
  """
  if _IsIOS():
    cmd_list.extend(['-arch=x86_64'] * num_archs)


def _GetBinaryPath(command):
  """Returns a relative path to the binary to be run by the command.

  Currently, following types of commands are supported (e.g. url_unittests):
  1. Run test binary direcly: "out/coverage/url_unittests <arguments>"
  2. Use xvfb.
    2.1. "python testing/xvfb.py out/coverage/url_unittests <arguments>"
    2.2. "testing/xvfb.py out/coverage/url_unittests <arguments>"
  3. Use iossim to run tests on iOS platform, please refer to testing/iossim.mm
    for its usage.
    3.1. "out/Coverage-iphonesimulator/iossim
          <iossim_arguments> -c <app_arguments>
          out/Coverage-iphonesimulator/url_unittests.app"


  Args:
    command: A command used to run a target.

  Returns:
    A relative path to the binary.
  """
  xvfb_script_name = os.extsep.join(['xvfb', 'py'])

  command_parts = shlex.split(command)
  if os.path.basename(command_parts[0]) == 'python':
    assert os.path.basename(command_parts[1]) == xvfb_script_name, (
        'This tool doesn\'t understand the command: "%s".' % command)
    return command_parts[2]

  if os.path.basename(command_parts[0]) == xvfb_script_name:
    return command_parts[1]

  if _IsIOSCommand(command):
    # For a given application bundle, the binary resides in the bundle and has
    # the same name with the application without the .app extension.
    app_path = command_parts[-1].rstrip(os.path.sep)
    app_name = os.path.splitext(os.path.basename(app_path))[0]
    return os.path.join(app_path, app_name)

  return command_parts[0]


def _IsIOSCommand(command):
  """Returns true if command is used to run tests on iOS platform."""
  return os.path.basename(shlex.split(command)[0]) == 'iossim'


def _VerifyTargetExecutablesAreInBuildDirectory(commands):
  """Verifies that the target executables specified in the commands are inside
  the given build directory."""
  for command in commands:
    binary_path = _GetBinaryPath(command)
    binary_absolute_path = os.path.abspath(os.path.normpath(binary_path))
    assert binary_absolute_path.startswith(BUILD_DIR), (
        'Target executable "%s" in command: "%s" is outside of '
        'the given build directory: "%s".' % (binary_path, command, BUILD_DIR))


def _ValidateBuildingWithClangCoverage():
  """Asserts that targets are built with Clang coverage enabled."""
  build_args = _GetBuildArgs()

  if (CLANG_COVERAGE_BUILD_ARG not in build_args or
      build_args[CLANG_COVERAGE_BUILD_ARG] != 'true'):
    assert False, ('\'{} = true\' is required in args.gn.'
                  ).format(CLANG_COVERAGE_BUILD_ARG)


def _ValidateCurrentPlatformIsSupported():
  """Asserts that this script suports running on the current platform"""
  target_os = _GetTargetOS()
  if target_os:
    current_platform = target_os
  else:
    current_platform = _GetHostPlatform()

  assert current_platform in [
      'linux', 'mac', 'chromeos', 'ios'
  ], ('Coverage is only supported on linux, mac, chromeos and ios.')


def _GetBuildArgs():
  """Parses args.gn file and returns results as a dictionary.

  Returns:
    A dictionary representing the build args.
  """
  global _BUILD_ARGS
  if _BUILD_ARGS is not None:
    return _BUILD_ARGS

  _BUILD_ARGS = {}
  build_args_path = os.path.join(BUILD_DIR, 'args.gn')
  assert os.path.exists(build_args_path), ('"%s" is not a build directory, '
                                           'missing args.gn file.' % BUILD_DIR)
  with open(build_args_path) as build_args_file:
    build_args_lines = build_args_file.readlines()

  for build_arg_line in build_args_lines:
    build_arg_without_comments = build_arg_line.split('#')[0]
    key_value_pair = build_arg_without_comments.split('=')
    if len(key_value_pair) != 2:
      continue

    key = key_value_pair[0].strip()

    # Values are wrapped within a pair of double-quotes, so remove the leading
    # and trailing double-quotes.
    value = key_value_pair[1].strip().strip('"')
    _BUILD_ARGS[key] = value

  return _BUILD_ARGS


def _VerifyPathsAndReturnAbsolutes(paths):
  """Verifies that the paths specified in |paths| exist and returns absolute
  versions.

  Args:
    paths: A list of files or directories.
  """
  absolute_paths = []
  for path in paths:
    absolute_path = os.path.join(SRC_ROOT_PATH, path)
    assert os.path.exists(absolute_path), ('Path: "%s" doesn\'t exist.' % path)

    absolute_paths.append(absolute_path)

  return absolute_paths


def _GetRelativePathToDirectoryOfFile(target_path, base_path):
  """Returns a target path relative to the directory of base_path.

  This method requires base_path to be a file, otherwise, one should call
  os.path.relpath directly.
  """
  assert os.path.dirname(base_path) != base_path, (
      'Base path: "%s" is a directory, please call os.path.relpath directly.' %
      base_path)
  base_dir = os.path.dirname(base_path)
  return os.path.relpath(target_path, base_dir)


def _GetBinaryPathsFromTargets(targets, build_dir):
  """Return binary paths from target names."""
  # FIXME: Derive output binary from target build definitions rather than
  # assuming that it is always the same name.
  binary_paths = []
  for target in targets:
    binary_path = os.path.join(build_dir, target)
    if _GetHostPlatform() == 'win':
      binary_path += '.exe'

    if os.path.exists(binary_path):
      binary_paths.append(binary_path)
    else:
      logging.warning(
          'Target binary "%s" not found in build directory, skipping.',
          os.path.basename(binary_path))

  return binary_paths


def _ParseCommandArguments():
  """Adds and parses relevant arguments for tool comands.

  Returns:
    A dictionary representing the arguments.
  """
  arg_parser = argparse.ArgumentParser()
  arg_parser.usage = __doc__

  arg_parser.add_argument(
      '-b',
      '--build-dir',
      type=str,
      required=True,
      help='The build directory, the path needs to be relative to the root of '
      'the checkout.')

  arg_parser.add_argument(
      '-o',
      '--output-dir',
      type=str,
      required=True,
      help='Output directory for generated artifacts.')

  arg_parser.add_argument(
      '-c',
      '--command',
      action='append',
      required=False,
      help='Commands used to run test targets, one test target needs one and '
      'only one command, when specifying commands, one should assume the '
      'current working directory is the root of the checkout. This option is '
      'incompatible with -p/--profdata-file option.')

  arg_parser.add_argument(
      '-p',
      '--profdata-file',
      type=str,
      required=False,
      help='Path to profdata file to use for generating code coverage reports. '
      'This can be useful if you generated the profdata file seperately in '
      'your own test harness. This option is ignored if run command(s) are '
      'already provided above using -c/--command option.')

  arg_parser.add_argument(
      '-f',
      '--filters',
      action='append',
      required=False,
      help='Directories or files to get code coverage for, and all files under '
      'the directories are included recursively.')

  arg_parser.add_argument(
      '-i',
      '--ignore-filename-regex',
      type=str,
      help='Skip source code files with file paths that match the given '
      'regular expression. For example, use -i=\'.*/out/.*|.*/third_party/.*\' '
      'to exclude files in third_party/ and out/ folders from the report.')

  arg_parser.add_argument(
      '--no-file-view',
      action='store_true',
      help='Don\'t generate the file view in the coverage report. When there '
      'are large number of html files, the file view becomes heavy and may '
      'cause the browser to freeze, and this argument comes handy.')

  arg_parser.add_argument(
      '-j',
      '--jobs',
      type=int,
      default=None,
      help='Run N jobs to build in parallel. If not specified, a default value '
      'will be derived based on CPUs availability. Please refer to '
      '\'ninja -h\' for more details.')

  arg_parser.add_argument(
      '-v',
      '--verbose',
      action='store_true',
      help='Prints additional output for diagnostics.')

  arg_parser.add_argument(
      '-l', '--log_file', type=str, help='Redirects logs to a file.')

  arg_parser.add_argument(
      'targets',
      nargs='+',
      help='The names of the test targets to run. If multiple run commands are '
      'specified using the -c/--command option, then the order of targets and '
      'commands must match, otherwise coverage generation will fail.')

  args = arg_parser.parse_args()
  return args


def Main():
  """Execute tool commands."""
  # Change directory to source root to aid in relative paths calculations.
  os.chdir(SRC_ROOT_PATH)

  # Setup coverage binaries even when script is called with empty params. This
  # is used by coverage bot for initial setup.
  DownloadCoverageToolsIfNeeded()

  args = _ParseCommandArguments()
  _ConfigureLogging(args)

  global BUILD_DIR
  BUILD_DIR = os.path.abspath(args.build_dir)
  global OUTPUT_DIR
  OUTPUT_DIR = os.path.abspath(args.output_dir)

  assert args.command or args.profdata_file, (
      'Need to either provide commands to run using -c/--command option OR '
      'provide prof-data file as input using -p/--profdata-file option.')

  assert not args.command or (len(args.targets) == len(args.command)), (
      'Number of targets must be equal to the number of test commands.')

  assert os.path.exists(BUILD_DIR), (
      'Build directory: "%s" doesn\'t exist. '
      'Please run "gn gen" to generate.' % BUILD_DIR)

  _ValidateCurrentPlatformIsSupported()
  _ValidateBuildingWithClangCoverage()

  absolute_filter_paths = []
  if args.filters:
    absolute_filter_paths = _VerifyPathsAndReturnAbsolutes(args.filters)

  if not os.path.exists(_GetCoverageReportRootDirPath()):
    os.makedirs(_GetCoverageReportRootDirPath())

  # Get profdate file and list of binary paths.
  if args.command:
    # A list of commands are provided. Run them to generate profdata file, and
    # create a list of binary paths from parsing commands.
    _VerifyTargetExecutablesAreInBuildDirectory(args.command)
    profdata_file_path = _CreateCoverageProfileDataForTargets(
        args.targets, args.command, args.jobs)
    binary_paths = [_GetBinaryPath(command) for command in args.command]
  else:
    # An input prof-data file is already provided. Just calculate binary paths.
    profdata_file_path = args.profdata_file
    binary_paths = _GetBinaryPathsFromTargets(args.targets, args.build_dir)

  binary_paths.extend(_GetSharedLibraries(binary_paths))

  logging.info('Generating code coverage report in html (this can take a while '
               'depending on size of target!).')
  per_file_coverage_summary = _GeneratePerFileCoverageSummary(
      binary_paths, profdata_file_path, absolute_filter_paths,
      args.ignore_filename_regex)
  _GeneratePerFileLineByLineCoverageInHtml(binary_paths, profdata_file_path,
                                           absolute_filter_paths,
                                           args.ignore_filename_regex)
  if not args.no_file_view:
    _GenerateFileViewHtmlIndexFile(per_file_coverage_summary)

  per_directory_coverage_summary = _CalculatePerDirectoryCoverageSummary(
      per_file_coverage_summary)
  _GeneratePerDirectoryCoverageInHtml(per_directory_coverage_summary,
                                      per_file_coverage_summary,
                                      args.no_file_view)
  _GenerateDirectoryViewHtmlIndexFile()

  component_to_directories = _ExtractComponentToDirectoriesMapping()
  per_component_coverage_summary = _CalculatePerComponentCoverageSummary(
      component_to_directories, per_directory_coverage_summary)
  _GeneratePerComponentCoverageInHtml(
      per_component_coverage_summary, component_to_directories,
      per_directory_coverage_summary, args.no_file_view)
  _GenerateComponentViewHtmlIndexFile(per_component_coverage_summary,
                                      args.no_file_view)

  # The default index file is generated only for the list of source files, needs
  # to overwrite it to display per directory coverage view by default.
  _OverwriteHtmlReportsIndexFile()
  _CleanUpOutputDir()

  html_index_file_path = 'file://' + os.path.abspath(_GetHtmlIndexPath())
  logging.info('Index file for html report is generated as: "%s".',
               html_index_file_path)


if __name__ == '__main__':
  sys.exit(Main())
