#!/usr/bin/env python3
#
# Copyright 2013 The Flutter Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import sys
import subprocess
import os
import argparse
import errno
import shutil

def GetLLVMBinDirectory():
  buildtool_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../buildtools")
  platform_dir = ""
  if sys.platform.startswith('linux'):
    platform_dir = "linux-x64"
  elif sys.platform == 'darwin':
    platform_dir = "mac-x64"
  else:
    raise Exception("Unknown/Unsupported platform.")
  llvm_bin_dir = os.path.abspath(os.path.join(buildtool_dir, platform_dir, "clang/bin"))
  if not os.path.exists(llvm_bin_dir):
    raise Exception("LLVM directory %s double not be located." % llvm_bin_dir)
  return llvm_bin_dir


def MakeDirs(new_dir):
  """A wrapper around os.makedirs() that emulates "mkdir -p"."""
  try:
    os.makedirs(new_dir)
  except OSError as e:
    if e.errno != errno.EEXIST:
      raise

def RemoveIfExists(path):
    if os.path.isdir(path) and not os.path.islink(path):
        shutil.rmtree(path)
    elif os.path.exists(path):
        os.remove(path)

def main():
  parser = argparse.ArgumentParser();

  parser.add_argument('-t', '--tests', nargs='+', dest='tests',
      required=True, help='The unit tests to run and gather coverage data on.')
  parser.add_argument('-o', '--output', dest='output',
      required=True, help='The output directory for coverage results.')
  parser.add_argument('-f', '--format', type=str, choices=['all', 'html', 'summary', 'lcov'],
      required=True, help='The type of coverage information to be displayed.')
  parser.add_argument('-a', '--args', nargs='+', dest='test_args',
      required=False, help='The arguments to pass to the unit test executable being run.')

  args = parser.parse_args()

  output = os.path.abspath(args.output)

  MakeDirs(output)

  generate_all_reports = args.format == "all"

  raw_profiles = []
  binaries = []

  # Run all unit tests and collect raw profiles.
  for test in args.tests:
    absolute_test_path = os.path.abspath(test)
    absolute_test_dir = os.path.dirname(absolute_test_path)
    test_name = os.path.basename(absolute_test_path)

    if not os.path.exists(absolute_test_path):
      print("Path %s does not exist." % absolute_test_path)
      return -1

    unstripped_test_path = os.path.join(absolute_test_dir, "exe.unstripped", test_name)

    if os.path.exists(unstripped_test_path):
      binaries.append(unstripped_test_path)
    else:
      binaries.append(absolute_test_path)

    raw_profile = absolute_test_path + ".rawprofile"

    RemoveIfExists(raw_profile)

    print("Running test %s to gather profile." % os.path.basename(absolute_test_path))

    test_command = [absolute_test_path]

    test_args = ' '.join(args.test_args).split()

    if test_args is not None:
      test_command += test_args

    subprocess.check_call(test_command, env={
      "LLVM_PROFILE_FILE":  raw_profile
    })

    if not os.path.exists(raw_profile):
      print("Could not find raw profile data for unit test run %s." % test)
      print("Did you build with the --coverage flag?")
      return -1

    raw_profiles.append(raw_profile)

  if len(raw_profiles) == 0:
    print("No raw profiles could be generated.")
    return -1

  binaries_flag = []
  for binary in binaries:
    binaries_flag.append('-object')
    binaries_flag.append(binary)

  llvm_bin_dir = GetLLVMBinDirectory()

  # Merge all raw profiles into a single profile.
  profdata_binary = os.path.join(llvm_bin_dir, "llvm-profdata")

  print("Merging %d raw profile(s) into single profile." % len(raw_profiles))
  merged_profile_path = os.path.join(output, "all.profile")
  RemoveIfExists(merged_profile_path)
  merge_command = [profdata_binary, "merge", "-sparse"] + raw_profiles + ["-o", merged_profile_path]
  subprocess.check_call(merge_command)
  print("Done.")

  if not os.path.exists(merged_profile_path):
    print("Could not generate or find merged profile %s." % merged_profile_path)
    return -1

  llvm_cov_binary = os.path.join(llvm_bin_dir, "llvm-cov")
  instr_profile_flag = "-instr-profile=%s" % merged_profile_path
  ignore_flags = "-ignore-filename-regex=third_party|unittest|fixture"

  # Generate the HTML report if specified.
  if generate_all_reports or args.format == 'html':
    print("Generating HTML report.")
    show_command = [llvm_cov_binary, "show"] + binaries_flag + [
      instr_profile_flag,
      "-format=html",
      "-output-dir=%s" % output,
      "-tab-size=2",
      ignore_flags,
    ]
    subprocess.check_call(show_command)
    print("Done.")

  # Generate a report summary if specified.
  if generate_all_reports or args.format == 'summary':
    print("Generating a summary report.")
    report_command = [llvm_cov_binary, "report"] + binaries_flag + [
      instr_profile_flag,
      ignore_flags,
    ]
    subprocess.check_call(report_command)
    print("Done.")

  # Generate a lcov summary if specified.
  if generate_all_reports or args.format == 'lcov':
    print("Generating LCOV report.")
    lcov_file = os.path.join(output, 'coverage.lcov')
    RemoveIfExists(lcov_file)
    lcov_command = [llvm_cov_binary, "export"] + binaries_flag + [
      instr_profile_flag,
      ignore_flags,
      "-format=lcov",
    ]
    with open(lcov_file, 'w') as lcov_redirect:
      subprocess.check_call(lcov_command, stdout=lcov_redirect)
    print("Done.")

  return 0

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