# Copyright 2018 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.
#
# The script intentionally does not have a shebang, as it is Py2/Py3 compatible.

import argparse
from collections import defaultdict
import functools
import jinja2
import json
import logging
import os
import re
import shutil
import subprocess
import sys

# 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'])


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_dir, output_path, table_entry_type):
    """Initializes _CoverageReportHtmlGenerator object.

    Args:
      output_dir: Path to the dir for writing coverage report to.
      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_dir = output_dir
    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_component_view, 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, key=functools.cmp_to_key(EntryCmp))

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

    directory_view_path = GetDirectoryViewPath(self._output_dir)
    directory_view_href = GetRelativePathToDirectoryOfFile(
        directory_view_path, self._output_path)

    component_view_href = None
    if not no_component_view:
      component_view_path = GetComponentViewPath(self._output_dir)
      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(self._output_dir)
      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)


class CoverageReportPostProcessor(object):
  """Post processing of code coverage reports produced by llvm-cov."""

  def __init__(self,
               output_dir,
               src_root_dir,
               summary_data,
               no_component_view,
               no_file_view,
               component_mappings={},
               path_equivalence=None):
    """Initializes CoverageReportPostProcessor object."""
    # Caller provided parameters.
    self.output_dir = output_dir
    self.src_root_dir = os.path.normpath(GetFullPath(src_root_dir))
    if not self.src_root_dir.endswith(os.sep):
      self.src_root_dir += os.sep
    self.summary_data = json.loads(summary_data)
    assert len(self.summary_data['data']) == 1
    self.no_component_view = no_component_view
    self.no_file_view = no_file_view

    # Mapping from components to directories
    self.component_to_directories = None
    if component_mappings:
      self._ExtractComponentToDirectoriesMapping(component_mappings)

    # The root directory that contains all generated coverage html reports.
    self.report_root_dir = GetCoverageReportRootDirPath(self.output_dir)

    # Path to the HTML file for the component view.
    self.component_view_path = GetComponentViewPath(self.output_dir)

    # Path to the HTML file for the directory view.
    self.directory_view_path = GetDirectoryViewPath(self.output_dir)

    # Path to the HTML file for the file view.
    self.file_view_path = GetFileViewPath(self.output_dir)

    # Path to the main HTML index file.
    self.html_index_path = GetHtmlIndexPath(self.output_dir)

    self.path_map = None
    if path_equivalence:

      def _PreparePath(path):
        path = os.path.normpath(path)
        if not path.endswith(os.sep):
          # A normalized path does not end with '/', unless it is a root dir.
          path += os.sep
        return path

      self.path_map = [_PreparePath(p) for p in path_equivalence.split(',')]
      assert len(self.path_map) == 2, 'Path equivalence argument is incorrect.'

  def _ExtractComponentToDirectoriesMapping(self, component_mappings):
    """Initializes a mapping from components to directories."""
    directory_to_component = component_mappings['dir-to-component']

    self.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 self.component_to_directories[component]:
        if directory.startswith(component_directory + '/'):
          found_parent_directory = True
          break

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

  def _MapToLocal(self, path):
    """Maps a path from the coverage data to a local path."""
    if not self.path_map:
      return path
    return path.replace(self.path_map[0], self.path_map[1], 1)

  def CalculatePerDirectoryCoverageSummary(self, 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 os.path.normpath(parent_dir) == os.path.normpath(self.src_root_dir):
          break
        parent_dir = os.path.dirname(parent_dir)

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

  def CalculatePerComponentCoverageSummary(self,
                                           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 self.component_to_directories:
      for directory in self.component_to_directories[component]:
        absolute_directory_path = GetFullPath(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 GeneratePerComponentCoverageInHtml(self, per_component_coverage_summary,
                                         per_directory_coverage_summary):
    """Generates per-component coverage reports in html."""
    logging.debug('Writing per-component coverage html reports.')
    for component in per_component_coverage_summary:
      self.GenerateCoverageInHtmlForComponent(component,
                                              per_component_coverage_summary,
                                              per_directory_coverage_summary)
    logging.debug('Finished writing per-component coverage html reports.')

  def GenerateComponentViewHtmlIndexFile(self, per_component_coverage_summary):
    """Generates the html index file for component view."""
    component_view_index_file_path = self.component_view_path
    logging.debug('Generating component view html index file as: "%s".',
                  component_view_index_file_path)
    html_generator = CoverageReportHtmlGenerator(
        self.output_dir, component_view_index_file_path, 'Component')
    for component in per_component_coverage_summary:
      html_generator.AddLinkToAnotherReport(
          self.GetCoverageHtmlReportPathForComponent(component), component,
          per_component_coverage_summary[component])

    # Do not create a totals row for the component view as the value is
    # incorrect due to failure to account for UNKNOWN component and some paths
    # belonging to multiple components.
    html_generator.WriteHtmlCoverageReport(self.no_component_view,
                                           self.no_file_view)
    logging.debug('Finished generating component view html index file.')

  def GenerateCoverageInHtmlForComponent(self, component_name,
                                         per_component_coverage_summary,
                                         per_directory_coverage_summary):
    """Generates coverage html report for a component."""
    component_html_report_path = self.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(
        self.output_dir, component_html_report_path, 'Path')

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

      html_generator.AddLinkToAnotherReport(
          self.GetCoverageHtmlReportPathForDirectory(dir_path),
          os.path.relpath(dir_path, self.src_root_dir),
          per_directory_coverage_summary[dir_absolute_path])

    html_generator.CreateTotalsEntry(
        per_component_coverage_summary[component_name])
    html_generator.WriteHtmlCoverageReport(self.no_component_view,
                                           self.no_file_view)

  def GetCoverageHtmlReportPathForComponent(self, 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(self.report_root_dir, 'components', html_report_name)

  def GetCoverageHtmlReportPathForDirectory(self, dir_path):
    """Given a directory path, returns the corresponding html report path."""
    assert os.path.isdir(
        self._MapToLocal(dir_path)), '"%s" is not a directory.' % dir_path
    html_report_path = os.path.join(
        GetFullPath(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 self.report_root_dir + html_report_path

  def GetCoverageHtmlReportPathForFile(self, file_path):
    """Given a file path, returns the corresponding html report path."""
    assert os.path.isfile(
        self._MapToLocal(file_path)), '"%s" is not a file.' % file_path
    html_report_path = os.extsep.join([GetFullPath(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 self.report_root_dir + html_report_path

  def GenerateFileViewHtmlIndexFile(self, per_file_coverage_summary,
                                    file_view_index_file_path):
    """Generates html index file for file view."""
    logging.debug('Generating file view html index file as: "%s".',
                  file_view_index_file_path)
    html_generator = CoverageReportHtmlGenerator(
        self.output_dir, 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(
          self.GetCoverageHtmlReportPathForFile(file_path),
          os.path.relpath(file_path, self.src_root_dir),
          per_file_coverage_summary[file_path])

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

  def GeneratePerFileCoverageSummary(self):
    """Generate per file coverage summary using coverage data in JSON format."""
    files_coverage_data = self.summary_data['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(self.src_root_dir), (
          '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 GeneratePerDirectoryCoverageInHtml(self, per_directory_coverage_summary,
                                         per_file_coverage_summary):
    """Generates per directory coverage breakdown in html."""
    logging.debug('Writing per-directory coverage html reports.')
    for dir_path in per_directory_coverage_summary:
      self.GenerateCoverageInHtmlForDirectory(
          dir_path, per_directory_coverage_summary, per_file_coverage_summary)

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

  def GenerateCoverageInHtmlForDirectory(self, dir_path,
                                         per_directory_coverage_summary,
                                         per_file_coverage_summary):
    """Generates coverage html report for a single directory."""
    html_generator = CoverageReportHtmlGenerator(
        self.output_dir, self.GetCoverageHtmlReportPathForDirectory(dir_path),
        'Path')

    for entry_name in os.listdir(self._MapToLocal(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 = self.GetCoverageHtmlReportPathForFile(
            entry_path)
        entry_coverage_summary = per_file_coverage_summary[entry_path]
      elif entry_path in per_directory_coverage_summary:
        entry_html_report_path = self.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(self.no_component_view,
                                           self.no_file_view)

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

    Note that the index file is already generated under src_root_dir, 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 = self.directory_view_path
    logging.debug('Generating directory view html index file as: "%s".',
                  directory_view_index_file_path)
    src_root_html_report_path = self.GetCoverageHtmlReportPathForDirectory(
        self.src_root_dir)
    WriteRedirectHtmlFile(directory_view_index_file_path,
                          src_root_html_report_path)
    logging.debug('Finished generating directory view html index file.')

  def RenameDefaultCoverageDirectory(self):
    """Rename the default coverage directory into platform specific name."""
    # 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(self.output_dir, 'coverage')
    if not os.path.exists(default_report_subdir_path):
      logging.error('Default coverage report dir does not exist: %s.',
                    default_report_subdir_path)

    if not os.path.exists(self.report_root_dir):
      os.mkdir(self.report_root_dir)

    MergeTwoDirectories(default_report_subdir_path, self.report_root_dir)

  def OverwriteHtmlReportsIndexFile(self):
    """Overwrites the root index file to redirect to the default view."""
    html_index_file_path = self.html_index_path
    directory_view_index_file_path = self.directory_view_path
    WriteRedirectHtmlFile(html_index_file_path, directory_view_index_file_path)

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

  def PrepareHtmlReport(self):
    self.RenameDefaultCoverageDirectory()

    per_file_coverage_summary = self.GeneratePerFileCoverageSummary()

    if not self.no_file_view:
      self.GenerateFileViewHtmlIndexFile(per_file_coverage_summary,
                                         self.file_view_path)

    per_directory_coverage_summary = self.CalculatePerDirectoryCoverageSummary(
        per_file_coverage_summary)

    self.GeneratePerDirectoryCoverageInHtml(per_directory_coverage_summary,
                                            per_file_coverage_summary)

    self.GenerateDirectoryViewHtmlIndexFile()

    if not self.no_component_view:
      per_component_coverage_summary = (
          self.CalculatePerComponentCoverageSummary(
              per_directory_coverage_summary))
      self.GeneratePerComponentCoverageInHtml(per_component_coverage_summary,
                                              per_directory_coverage_summary)
      self.GenerateComponentViewHtmlIndexFile(per_component_coverage_summary)

    # 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.
    self.OverwriteHtmlReportsIndexFile()
    self.CleanUpOutputDir()

    html_index_file_path = 'file://' + GetFullPath(self.html_index_path)
    logging.info('Index file for html report is generated as: "%s".',
                 html_index_file_path)


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


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


def GetCoverageReportRootDirPath(output_dir):
  """The root directory that contains all generated coverage html reports."""
  return os.path.join(output_dir, GetHostPlatform())


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


def GetFileViewPath(output_dir):
  """Path to the HTML file for the file view."""
  return os.path.join(
      GetCoverageReportRootDirPath(output_dir), FILE_VIEW_INDEX_FILE)


def GetHtmlIndexPath(output_dir):
  """Path to the main HTML index file."""
  return os.path.join(GetCoverageReportRootDirPath(output_dir), INDEX_HTML_FILE)


def GetFullPath(path):
  """Return full absolute path."""
  return os.path.abspath(os.path.expandvars(os.path.expanduser(path)))


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 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 GetSharedLibraries(binary_paths, build_dir, otool_path):
  """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[.0-9]*\s=>\s(.*' + build_dir +
                                   r'.*\.so[.0-9]*)\s.*')
  elif sys.platform.startswith('darwin'):
    otool = otool_path if otool_path else 'otool'
    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).decode('utf-8', 'ignore')

  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, 'rb') as f:
      data = f.read()

    # Do not add non-instrumented libraries. Otherwise, llvm-cov errors outs.
    if b'__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 MergeTwoDirectories(src_dir_path, dst_dir_path):
  """Merge src_dir_path directory into dst_path directory."""
  for filename in os.listdir(src_dir_path):
    dst_path = os.path.join(dst_dir_path, filename)
    if os.path.exists(dst_path):
      shutil.rmtree(dst_path)
    os.rename(os.path.join(src_dir_path, filename), dst_path)
  shutil.rmtree(src_dir_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 _CmdSharedLibraries(args):
  """Handles 'shared_libs' command."""
  if not args.object:
    logging.error('No binaries are specified.')
    return 1

  library_paths = GetSharedLibraries(args.object, args.build_dir, None)
  if not library_paths:
    return 0

  # Print output in the format that can be passed to llvm-cov tool.
  output = ' '.join(
      '-object=%s' % os.path.normpath(path) for path in library_paths)
  print(output)
  return 0


def _CmdPostProcess(args):
  """Handles 'post_process' command."""
  with open(args.summary_file) as f:
    summary_data = f.read()

  processor = CoverageReportPostProcessor(
      args.output_dir,
      args.src_root_dir,
      summary_data,
      no_component_view=True,
      no_file_view=False,
      path_equivalence=args.path_equivalence)
  processor.PrepareHtmlReport()


def Main():
  parser = argparse.ArgumentParser(
      'coverage_utils', description='Code coverage utils.')
  parser.add_argument(
      '-v',
      '--verbose',
      action='store_true',
      help='Prints additional debug output.')

  subparsers = parser.add_subparsers(dest='command')

  shared_libs_parser = subparsers.add_parser(
      'shared_libs', help='Detect shared libraries.')
  shared_libs_parser.add_argument(
      '-build-dir', help='Path to the build dir.', required=True)
  shared_libs_parser.add_argument(
      '-object',
      action='append',
      help='Path to the binary using shared libs.',
      required=True)

  post_processing_parser = subparsers.add_parser(
      'post_process', help='Post process a report.')
  post_processing_parser.add_argument(
      '-output-dir', help='Path to the report dir.', required=True)
  post_processing_parser.add_argument(
      '-src-root-dir', help='Path to the src root dir.', required=True)
  post_processing_parser.add_argument(
      '-summary-file', help='Path to the summary file.', required=True)
  post_processing_parser.add_argument(
      '-path-equivalence',
      help='Map the paths in the coverage data to local '
      'source files path (=<from>,<to>)')

  args = parser.parse_args()
  ConfigureLogging(args.verbose)

  if args.command == 'shared_libs':
    return _CmdSharedLibraries(args)
  elif args.command == 'post_process':
    return _CmdPostProcess(args)
  else:
    parser.print_help(sys.stderr)


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