#!/usr/bin/env python3

"""
Manages the code coverage data generated by bazel kcov and kcov_everything
configurations. See instructions here:
https://drake.mit.edu/bazel.html?highlight=kcov#kcov
"""

import argparse
import glob
import shutil
import subprocess
import os
import sys

# This bit may need adjusting if this file moves to a new directory.
WORKSPACE = os.path.dirname(os.path.dirname(os.path.dirname(
    os.path.abspath(__file__))))


def find_kcov_data():
    """Finds the kcov data of individual test runs within the tree linked by
    bazel-testlogs.
    """
    return glob.glob(os.path.join(WORKSPACE, 'bazel-testlogs/**/kcov'),
                     recursive=True)


def clean(args):
    """Implements the clean subcommand."""
    for d in find_kcov_data():
        shutil.rmtree(d)


def do_merge(output_dir):
    """Merges the kcov data of individual test runs into output_dir."""
    dirs = find_kcov_data()
    if not dirs:
        sys.exit("Error: no kcov data to merge")

    # Smooth over kcov location change from Bionic to Focal.
    newenv = os.environ.copy()
    newenv['PATH'] = "/opt/kcov/35/bin:" + newenv['PATH']

    cmd = ['kcov', '--merge', output_dir] + dirs
    subprocess.run(cmd, env=newenv)


def ci_merge(args):
    """Implements the ci_merge subcommand."""
    do_merge(os.path.join(WORKSPACE, "bazel-kcov"))


def merge(args):
    """Implements the merge subcommand."""
    do_merge(args.output_dir)


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    subparsers = parser.add_subparsers(
        help='subcommand to run', dest='subcommand')
    subparsers.required = True

    parser_ci_merge = subparsers.add_parser(
        'ci_merge', help='like merge, but verbose, and always to bazel-kcov.'
        ' For now, succeeds even if no data is available; see #10617.')
    parser_ci_merge.set_defaults(func=ci_merge)

    parser_clean = subparsers.add_parser(
        'clean', help='remove all kcov data from the bazel-testlogs tree')
    parser_clean.set_defaults(func=clean)

    parser_merge = subparsers.add_parser(
        'merge',
        help='merge all kcov data from the bazel-testlogs tree to OUTPUT-DIR')
    parser_merge.add_argument(
        'output_dir', metavar='OUTPUT-DIR',
        help='output directory for merged kcov data;'
        ' if not existing it will be created.')
    parser_merge.set_defaults(func=merge)

    args = parser.parse_args()
    args.func(args)


if __name__ == '__main__':
    main()
