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

    return self.CombineAbsolutePaths(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'])

    return self.CombineAbsolutePaths(self.report_root_dir, html_report_path)

  def CombineAbsolutePaths(self, path1, path2):
    if GetHostPlatform() == 'win':
      # Absolute paths in Windows may start with a drive letter and colon.
      # Remove them from the second path before appending to the first.
      _, path2 = os.path.splitdrive(path2)

    # '+' is used instead of os.path.join because both of them are absolute
    # paths and os.path.join ignores the first path.
    return path1 + path2

  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())
