#!/usr/bin/env python

from __future__ import print_function

'''Prepare a code coverage artifact.

- Collate raw profiles into one indexed profile.
- Generate html reports for the given binaries.

Caution: The positional arguments to this script must be specified before any 
optional arguments, such as --restrict.
'''

import argparse
import glob
import os
import subprocess
import sys

def merge_raw_profiles(host_llvm_profdata, profile_data_dir, preserve_profiles):
    print(':: Merging raw profiles...', end='')
    sys.stdout.flush()
    raw_profiles = glob.glob(os.path.join(profile_data_dir, '*.profraw'))
    manifest_path = os.path.join(profile_data_dir, 'profiles.manifest')
    profdata_path = os.path.join(profile_data_dir, 'Coverage.profdata')
    with open(manifest_path, 'w') as manifest:
        manifest.write('\n'.join(raw_profiles))
    subprocess.check_call([host_llvm_profdata, 'merge', '-sparse', '-f',
                           manifest_path, '-o', profdata_path])
    if not preserve_profiles:
        for raw_profile in raw_profiles:
            os.remove(raw_profile)
    os.remove(manifest_path)
    print('Done!')
    return profdata_path

def prepare_html_report(host_llvm_cov, profile, report_dir, binaries,
                        restricted_dirs, compilation_dir):
    print(':: Preparing html report for {0}...'.format(binaries), end='')
    sys.stdout.flush()
    objects = []
    for i, binary in enumerate(binaries):
        if i == 0:
            objects.append(binary)
        else:
            objects.extend(('-object', binary))
    invocation = [host_llvm_cov, 'show'] + objects + ['-format', 'html',
                  '-instr-profile', profile, '-o', report_dir,
                  '-show-line-counts-or-regions', '-Xdemangler', 'c++filt',
                  '-Xdemangler', '-n'] + restricted_dirs
    if compilation_dir:
        invocation += ['-compilation-dir=' + compilation_dir]
    subprocess.check_call(invocation)
    with open(os.path.join(report_dir, 'summary.txt'), 'wb') as Summary:
        subprocess.check_call([host_llvm_cov, 'report'] + objects +
                               ['-instr-profile', profile] + restricted_dirs,
                               stdout=Summary)
    print('Done!')

def prepare_html_reports(host_llvm_cov, profdata_path, report_dir, binaries,
                         unified_report, restricted_dirs, compilation_dir):
    if unified_report:
        prepare_html_report(host_llvm_cov, profdata_path, report_dir, binaries,
                            restricted_dirs, compilation_dir)
    else:
        for binary in binaries:
            binary_report_dir = os.path.join(report_dir,
                                             os.path.basename(binary))
            prepare_html_report(host_llvm_cov, profdata_path, binary_report_dir,
                                [binary], restricted_dirs, compilation_dir)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('host_llvm_profdata', help='Path to llvm-profdata')
    parser.add_argument('host_llvm_cov', help='Path to llvm-cov')
    parser.add_argument('profile_data_dir',
                       help='Path to the directory containing the raw profiles')
    parser.add_argument('report_dir',
                       help='Path to the output directory for html reports')
    parser.add_argument('binaries', metavar='B', type=str, nargs='*',
                       help='Path to an instrumented binary')
    parser.add_argument('--only-merge', action='store_true',
                        help='Only merge raw profiles together, skip report '
                             'generation')
    parser.add_argument('--preserve-profiles',
                       help='Do not delete raw profiles', action='store_true')
    parser.add_argument('--use-existing-profdata',
                       help='Specify an existing indexed profile to use')
    parser.add_argument('--unified-report', action='store_true',
                       help='Emit a unified report for all binaries')
    parser.add_argument('--restrict', metavar='R', type=str, nargs='*',
                       default=[],
                       help='Restrict the reporting to the given source paths'
                   ' (must be specified after all other positional arguments)')
    parser.add_argument('-C', '--compilation-dir', type=str, default="",
                       help='The compilation directory of the binary')
    args = parser.parse_args()

    if args.use_existing_profdata and args.only_merge:
        print('--use-existing-profdata and --only-merge are incompatible')
        exit(1)

    if args.use_existing_profdata:
        profdata_path = args.use_existing_profdata
    else:
        profdata_path = merge_raw_profiles(args.host_llvm_profdata,
                                           args.profile_data_dir,
                                           args.preserve_profiles)

    if not len(args.binaries):
        print('No binaries specified, no work to do!')
        exit(1)

    if not args.only_merge:
        prepare_html_reports(args.host_llvm_cov, profdata_path, args.report_dir,
                             args.binaries, args.unified_report, args.restrict, 
                             args.compilation_dir)
