#!/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):
    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
    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):
    if unified_report:
        prepare_html_report(host_llvm_cov, profdata_path, report_dir, binaries,
                            restricted_dirs)
    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)

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