#!/usr/bin/env 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.

from __future__ import print_function

import argparse
import logging
import os
import subprocess
import sys

import SimpleHTTPServer
import SocketServer

HELP_MESSAGE = """
This script helps to generate code coverage report. It uses Clang Source-based
Code coverage (https://clang.llvm.org/docs/SourceBasedCodeCoverage.html).

The output is a directory with HTML files that can be inspected via local web
server (e.g. "python -m SimpleHTTPServer").

In order to generate code coverage report, you need to build the target program
with "use_clang_coverage=true" GN flag. You should also explicitly use the flag
"is_component_build=false" as explained at the end of this paragraph.
use_component_build is not compatible with sanitizer flags: "is_asan",
"is_msan", etc. It is also incompatible with "optimize_for_fuzzing" and with
"is_component_build". Beware that if "is_debug" is true (it defaults to true),
then "is_component_build" will be set to true unless specified false as an
argument. So it is best to pass is_component_build=false when using
"use_clang_coveage".

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

cd <chromium_checkout_dir>/src
gn gen //out/coverage --args='use_clang_coverage=true use_libfuzzer=true \
is_component_build=false'
ninja -C out/coverage -j100 pdfium_fuzzer
./testing/libfuzzer/coverage.py \\
  --output="coverage_out" \\
  --command="out/coverage/pdfium_fuzzer -runs=<runs> <corpus_dir>"
  --filter third_party/pdfium/ pdf/

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.
Then, open http://localhost:9000/report.html to see coverage report.

For Googlers, there are examples available at go/chrome-code-coverage-examples.

If you have any questions, please send an email to fuzzing@chromium.org.
"""

HTML_FILE_EXTENSION = '.html'

CHROME_SRC_PATH = os.path.dirname(
    os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
LLVM_BUILD_PATH = os.path.join(CHROME_SRC_PATH, 'third_party', 'llvm-build')
LLVM_BIN_PATH = os.path.join(LLVM_BUILD_PATH, 'Release+Asserts', 'bin')
LLVM_COV_PATH = os.path.join(LLVM_BIN_PATH, 'llvm-cov')
LLVM_PROFDATA_PATH = os.path.join(LLVM_BIN_PATH, 'llvm-profdata')

LLVM_PROFILE_FILE_NAME = 'coverage.profraw'
LLVM_COVERAGE_FILE_NAME = 'coverage.profdata'

REPORT_FILENAME = 'report.html'

REPORT_TEMPLATE = """<!DOCTYPE html>
<html>
<head>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<meta charset='UTF-8'>
<link rel="stylesheet" type="text/css" href="/style.css">
</head>
<body>
{table_data}
</body></html>"""

SINGLE_FILE_START_MARKER = '<!doctype html><html>'
SINGLE_FILE_END_MARKER = '</body></html>'

SOURCE_FILENAME_START_MARKER = (
    "<body><div class='centered'><table><div class='source-name-title'><pre>")
SOURCE_FILENAME_END_MARKER = '</pre>'

STYLE_START_MARKER = '<style>'
STYLE_END_MARKER = '</style>'
STYLE_FILENAME = 'style.css'

ZERO_FUNCTION_FILE_TEXT = 'Files which contain no functions'

HTTP_PORT = 9000
COVERAGE_REPORT_LINK = 'http://127.0.0.1:%d/report.html' % HTTP_PORT

LARGE_BINARY_THRESHOLD = 128 * 2 ** 20


def CheckBinaryAndArgs(executable_path, filters):
  """Verify that the given file has been built with coverage instrumentation,
  also perform check for "--filter" argument and for the binary size."""
  CheckFilterArgument(filters)

  with open(executable_path) as file_handle:
    data = file_handle.read()

  if len(data) > LARGE_BINARY_THRESHOLD and not filters:
    logging.warning('The target binary is quite large. Generating the full '
                    'coverage report may take a while. To generate the report '
                    'faster, consider using the "--filter" argument to specify '
                    'the source code files and directories shown in the report.'
                    )

  # For minimum threshold reference, tiny "Hello World" program has count of 34.
  if data.count('__llvm_profile') > 20:
    return

  logging.error('It looks like the target binary has been compiled without '
                'coverage instrumentation.')
  print('Have you used use_clang_coverage=true flag in GN args? [y/N]')
  answer = raw_input()
  if not answer.lower().startswith('y'):
    print('Exiting.')
    sys.exit(-1)


def CheckFilterArgument(filters):
  """Verify that all the paths specified in --filter arg exist."""
  for path in filters:
    if not os.path.exists(path):
      logging.error('The path specified does not exist: %s.' % path)
      sys.exit(-1)


def CreateOutputDir(dir_path):
  """Create a directory for the script output files."""
  if not os.path.exists(dir_path):
    os.mkdir(dir_path)
    return

  if os.path.isdir(dir_path):
    logging.warning('%s already exists.', dir_path)
    return

  logging.error('%s exists and does not point to a directory.', dir_path)
  raise Exception('Invalid --output argument specified.')


def DownloadCoverageToolsIfNeeded():
  """Temporary solution to download llvm-profdata and llvm-cov tools."""
  # TODO(mmoroz): remove this function once tools get included to Clang bundle:
  # https://chromium-review.googlesource.com/c/chromium/src/+/688221
  clang_script_path = os.path.join(CHROME_SRC_PATH, 'tools', 'clang', 'scripts')
  sys.path.append(clang_script_path)
  import update as clang_update
  import urllib2

  def _GetRevisionFromStampFile(file_path):
    """Read the build stamp file created by tools/clang/scripts/update.py."""
    if not os.path.exists(file_path):
      return 0, 0

    with open(file_path) as file_handle:
      revision_stamp_data = file_handle.readline().strip()
    revision_stamp_data = revision_stamp_data.split('-')
    return int(revision_stamp_data[0]), int(revision_stamp_data[1])

  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)

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

  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 sys.platform == 'win32' or sys.platform == 'cygwin':
    coverage_tools_url = clang_update.CDS_URL + '/Win/' + coverage_tools_file
  elif sys.platform == 'darwin':
    coverage_tools_url = clang_update.CDS_URL + '/Mac/' + coverage_tools_file
  else:
    assert sys.platform.startswith('linux')
    coverage_tools_url = (
        clang_update.CDS_URL + '/Linux_x64/' + coverage_tools_file)

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

  return clang_revision


def ExtractAndFixFilename(data, source_dir):
  """Extract full paths to source code files and replace with relative paths."""
  filename_start = data.find(SOURCE_FILENAME_START_MARKER)
  if filename_start == -1:
    logging.error('Failed to extract source code filename.')
    raise Exception('Failed to process coverage dump.')

  filename_start += len(SOURCE_FILENAME_START_MARKER)
  filename_end = data[filename_start:].find(SOURCE_FILENAME_END_MARKER)
  if filename_end == -1:
    logging.error('Failed to extract source code filename.')
    raise Exception('Failed to process coverage dump.')

  filename_end += filename_start

  filename = data[filename_start:filename_end]

  source_dir = os.path.abspath(source_dir)

  if not filename.startswith(source_dir):
    logging.error('Invalid source code path ("%s") specified.\n'
                  'Coverage dump refers to "%s".', source_dir, filename)
    raise Exception('Failed to process coverage dump.')

  filename = filename[len(source_dir):]
  filename = filename.lstrip('/\\')

  # Replace the filename with the shorter version.
  data = data[:filename_start] + filename + data[filename_end:]
  return filename, data


def GenerateReport(report_data):
  """Build HTML page with the summary report and links to individual files."""
  table_data = '<table class="centered">\n'
  report_lines = report_data.splitlines()

  # Write header.
  table_data += '  <tr class="source-name-title">\n'
  for column in report_lines[0].split('  '):
    if not column:
      continue
    table_data += '    <th><pre>%s</pre></th>\n' % column
  table_data += '  </tr>\n'

  for line in report_lines[1:-1]:
    if not line or line.startswith('---'):
      continue

    if line.startswith(ZERO_FUNCTION_FILE_TEXT):
      table_data += '  <tr class="source-name-title">\n'
      table_data += (
          '    <th class="column-entry-left"><pre>%s</pre></th>\n' % line)
      table_data += '  </tr>\n'
      continue

    table_data += '  <tr>\n'

    columns = line.split()

    # First column is a file name, build a link.
    table_data += ('    <td class="column-entry-left">\n'
                   '      <a href="/%s"><pre>%s</pre></a>\n'
                   '    </td>\n') % (columns[0] + HTML_FILE_EXTENSION,
                                     columns[0])

    for column in columns[1:]:
      table_data += '    <td class="column-entry"><pre>%s</pre></td>\n' % column
    table_data += '  </tr>\n'

  # Write the last "TOTAL" row.
  table_data += '  <tr class="source-name-title">\n'
  for column in report_lines[-1].split():
    table_data += '    <td class="column-entry"><pre>%s</pre></td>\n' % column
  table_data += '  </tr>\n'
  table_data += '</table>\n'

  return REPORT_TEMPLATE.format(table_data=table_data)


def GenerateSources(executable_path, output_dir, source_dir, filters,
                    coverage_file):
  """Generate coverage visualization for source code files."""
  llvm_cov_command = [
      LLVM_COV_PATH, 'show', '-format=html', executable_path,
      '-instr-profile=%s' % coverage_file
  ]

  for path in filters:
    llvm_cov_command.append(path)

  data = subprocess.check_output(llvm_cov_command)

  # Extract CSS style from the data.
  style_start = data.find(STYLE_START_MARKER)
  style_end = data.find(STYLE_END_MARKER)
  if style_end <= style_start or style_start == -1:
    logging.error('Failed to extract CSS style from coverage report.')
    raise Exception('Failed to process coverage dump.')

  style_data = data[style_start + len(STYLE_START_MARKER):style_end]

  # Add hover for table <tr>.
  style_data += '\ntr:hover { background-color: #eee; }'

  with open(os.path.join(output_dir, STYLE_FILENAME), 'w') as file_handle:
    file_handle.write(style_data)
  style_length = (
      len(style_data) + len(STYLE_START_MARKER) + len(STYLE_END_MARKER))

  # Extract every source code file. Use "offset" to avoid creating new strings.
  offset = 0
  while True:
    file_start = data.find(SINGLE_FILE_START_MARKER, offset)
    if file_start == -1:
      break

    file_end = data.find(SINGLE_FILE_END_MARKER, offset)
    if file_end == -1:
      break

    file_end += len(SINGLE_FILE_END_MARKER)
    offset += file_end - file_start

    # Remove <style> as it's always the same and has been extracted separately.
    file_data = ReplaceStyleWithCss(data[file_start:file_end], style_length,
                                    STYLE_FILENAME)

    filename, file_data = ExtractAndFixFilename(file_data, source_dir)
    file_path = os.path.join(output_dir, filename)
    dirname = os.path.dirname(file_path)

    try:
      os.makedirs(dirname)
    except OSError:
      pass

    with open(file_path + HTML_FILE_EXTENSION, 'w') as file_handle:
      file_handle.write(file_data)


def GenerateSummary(executable_path, output_dir, filters, coverage_file,
                    clang_revision):
  """Generate code coverage summary report (i.e. a table with all files)."""
  llvm_cov_command = [
      LLVM_COV_PATH, 'report', executable_path,
      '-instr-profile=%s' % coverage_file
  ]

  for path in filters:
    llvm_cov_command.append(path)

  data = subprocess.check_output(llvm_cov_command)
  report = GenerateReport(data)

  with open(os.path.join(output_dir, REPORT_FILENAME), 'w') as file_handle:
    # TODO(mmoroz): remove this hacky warning after next clang roll.
    if filters and clang_revision < 315685:
      report = ('Warning: the report below contains information for all the '
                'sources even though you used "--filter" option. This bug has '
                'been fixed upstream. It will be fixed in Chromium after next '
                'clang roll (https://reviews.llvm.org/rL315685).<br>' + report)
    file_handle.write(report)


def ServeReportOnHTTP(output_directory):
  """Serve report directory on HTTP."""
  os.chdir(output_directory)

  SocketServer.TCPServer.allow_reuse_address = True
  httpd = SocketServer.TCPServer(('', HTTP_PORT),
                                 SimpleHTTPServer.SimpleHTTPRequestHandler)
  print('Load coverage report using %s. Press Ctrl+C to exit.' %
        COVERAGE_REPORT_LINK)

  try:
    httpd.serve_forever()
  except KeyboardInterrupt:
    httpd.server_close()


def ProcessCoverageDump(profile_file, coverage_file):
  """Process and convert raw LLVM profile data into coverage data format."""
  print('Processing coverage dump and generating visualization.')
  merge_command = [
      LLVM_PROFDATA_PATH, 'merge', '-sparse', profile_file, '-o', coverage_file
  ]
  data = subprocess.check_output(merge_command)

  if not os.path.exists(coverage_file) or not os.path.getsize(coverage_file):
    logging.error('%s is either not created or empty:\n%s', coverage_file, data)
    raise Exception('Failed to merge coverage information after command run.')


def ReplaceStyleWithCss(data, style_data_length, css_file_path):
  """Replace <style></style> data with the include of common style.css file."""
  style_start = data.find(STYLE_START_MARKER)
  # Since "style" data is always the same, try some optimization here.
  style_end = style_start + style_data_length
  if (style_end > len(data) or
      data[style_end - len(STYLE_END_MARKER):style_end] != STYLE_END_MARKER):
    # Looks like our optimization has failed, find end of "style" data.
    style_end = data.find(STYLE_END_MARKER)
    if style_end <= style_start or style_start == -1:
      logging.error('Failed to extract CSS style from coverage report.')
      raise Exception('Failed to process coverage dump.')
    style_end += len(STYLE_END_MARKER)

  css_include = (
      '<link rel="stylesheet" type="text/css" href="/%s">' % css_file_path)
  result = '\n'.join([data[:style_start], css_include, data[style_end:]])
  return result


def RunCommand(command, profile_file):
  """Run the given command in order to generate raw LLVM profile data."""
  print('Running "%s".' % command)
  print('-' * 80)
  os.environ['LLVM_PROFILE_FILE'] = profile_file
  os.system(command)
  print('-' * 80)
  print('Finished command execution.')

  if not os.path.exists(profile_file) or not os.path.getsize(profile_file):
    logging.error('%s is either not created or empty.', profile_file)
    raise Exception('Failed to dump coverage information during command run.')


def main():
  """The main routing for processing the arguments and generating coverage."""
  parser = argparse.ArgumentParser(
      description=HELP_MESSAGE,
      formatter_class=argparse.RawDescriptionHelpFormatter)
  parser.add_argument(
      '--command',
      required=True,
      help='The command to run target binary for which code coverage is '
      'required.')
  parser.add_argument(
      '--source',
      required=False,
      default=CHROME_SRC_PATH,
      help='Location of chromium source checkout, if it differs from '
      'current checkout: %s.' % CHROME_SRC_PATH)
  parser.add_argument(
      '--output',
      required=True,
      help='Directory where code coverage files will be written to.')
  parser.add_argument(
      '--filter',
      required=False,
      nargs='+',
      default = [],
      help='(Optional) Paths to source code files/directories shown in the '
      'report. By default, the report shows all the sources compiled and '
      'linked into the target executable.')

  if not len(sys.argv[1:]):
    # Print help when no arguments are provided on command line.
    parser.print_help()
    parser.exit()

  args = parser.parse_args()

  executable_path = args.command.split()[0]

  CheckBinaryAndArgs(executable_path, args.filter)

  clang_revision = DownloadCoverageToolsIfNeeded()

  CreateOutputDir(args.output)
  profile_file = os.path.join(args.output, LLVM_PROFILE_FILE_NAME)
  RunCommand(args.command, profile_file)

  coverage_file = os.path.join(args.output, LLVM_COVERAGE_FILE_NAME)
  ProcessCoverageDump(profile_file, coverage_file)

  GenerateSummary(executable_path, args.output, args.filter, coverage_file,
                  clang_revision)
  GenerateSources(executable_path, args.output, args.source, args.filter,
                  coverage_file)

  ServeReportOnHTTP(args.output)

  print('Done.')


if __name__ == '__main__':
  main()
