#!/usr/bin/env fuchsia-vendored-python

# Copyright 2020 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This program generates a combined coverage report for all host-side dart tests.
# See example_commands and arg help strings in ParseArgs() for usage.
#
# Implementation sketch:
# Search the host_tests directory for tests that use dart-tools/fuchsia_tester.
# Run each test with --coverage and --coverage-path.
# Combine the coverage data from each test into one.
# Generate an HTML report.
#
# This is all pretty hacky. Longer term efforts to make this more automatic and
# less hacky tracked by fxbug.dev/9302.

import argparse
import collections
import distutils.spawn
import glob
import os
from multiprocessing.pool import ThreadPool
import paths
import re
import subprocess
import sys
import tempfile

TestResult = collections.namedtuple(
    'TestResult', ('exit_code', 'coverage_data_path', 'package_dir'))
DEV_NULL = open('/dev/null', 'w')
LCOV = 'lcov'
GENHTML = 'genhtml'


def ParseArgs():
    example_commands = """

  Examples:
  $ report_coverage.py --report-dir /tmp/cov
  $ report_coverage.py --test-patterns 'foo_*_test,bar_test' --report-dir ...
  $ report_coverage.py --out-dir out/x64 --report-dir ...
  """
    p = argparse.ArgumentParser(
        description='Generates a coverage report for dart tests',
        epilog=example_commands,
        formatter_class=argparse.RawDescriptionHelpFormatter)

    p.add_argument(
        '--report-dir',
        type=str,
        help='Where to write the report. Will be created if needed',
        required=True)
    p.add_argument(
        '--test-patterns',
        type=str,
        help=(
            'Comma-separated list of glob patterns to match against test file '
            'base names'),
        default='*')
    p.add_argument('--out-dir', type=str, help='fuchsia build out dir')

    return p.parse_args()


def OutDir(args):
    if args.out_dir:
        out_dir = args.out_dir

        if not os.path.isabs(out_dir):
            out_dir = os.path.join(paths.FUCHSIA_ROOT, out_dir)

        if not os.path.isdir(out_dir):
            sys.exit(out_dir + ' is not a directory')
        return out_dir

    if os.environ.get('FUCHSIA_BUILD_DIR'):
        return os.environ.get('FUCHSIA_BUILD_DIR')

    fuchsia_dir = os.environ.get('FUCHSIA_DIR', paths.FUCHSIA_ROOT)
    fuchsia_config_file = os.path.join(fuchsia_dir, '.fx-build-dir')
    if os.path.isfile(fuchsia_config_file):
        fuchsia_config = open(fuchsia_config_file).read()
        return os.path.join(fuchsia_dir, fuchsia_config.strip())

    return None


class TestRunner(object):

    def __init__(self, out_dir):
        self.out_dir = out_dir

    def RunTest(self, test_path):
        # This whole function super hacky. Assumes implementation details which are
        # not meant to be public.

        # test_path actually refers to a script that executes other tests.
        # The other tests that get executed go into this list.
        leaf_test_paths = []
        test_lines = open(test_path, 'r').readlines()
        # We expect a script that starts with shebang.
        if not test_lines or not test_lines[0].startswith('#!'):
            return []
        for test_line in test_lines[1:]:  # Skip the shebang.
            test_line_parts = test_line.strip().split()
            if not test_line_parts:
                continue
            if os.path.join(self.out_dir, 'dartlang',
                            'gen') in test_line_parts[0]:
                leaf_test_paths.append(test_line_parts[0])
        results = [self._RunLeafTest(p) for p in leaf_test_paths]
        return [result for result in results if result]  # filter None

    def _RunLeafTest(self, test_path):
        test_lines = open(test_path, 'r').readlines()
        for test_line in test_lines:
            test_line_parts = test_line.strip().split()
            if not test_line_parts:
                continue
            if test_line_parts[0].endswith('dart-tools/fuchsia_tester'):
                is_dart_test = True
            elif test_line_parts[0].startswith('--test-directory='):
                test_directory = test_line_parts[0].split('=')[1]
        if not is_dart_test:
            return None
        if not test_directory:
            raise ValueError(
                'Failed to find --test-directory arg in %s' % test_path)
        coverage_data_handle, coverage_data_path = tempfile.mkstemp()
        os.close(coverage_data_handle)
        exit_code = subprocess.call(
            (
                test_path, '--coverage',
                '--coverage-path=%s' % coverage_data_path),
            stdout=DEV_NULL,
            stderr=DEV_NULL)
        if not os.stat(coverage_data_path).st_size:
            print(
                '%s produced no coverage data' % os.path.basename(test_path),
                file=sys.stderr)
            return None
        return TestResult(
            exit_code, coverage_data_path, os.path.dirname(test_directory))


def MakeRelativePathsAbsolute(test_result):
    """Change source-file paths from relative-to-the-package to absolute."""
    with open(test_result.coverage_data_path, 'r+') as coverage_data_file:
        fixed_data = coverage_data_file.read().replace(
            'SF:', 'SF:%s/' % test_result.package_dir)
        coverage_data_file.seek(0)
        coverage_data_file.write(fixed_data)


def CombineCoverageData(test_results):
    output_handle, output_path = tempfile.mkstemp()
    os.close(output_handle)
    lcov_cmd = [LCOV, '--output-file', output_path]
    for test_result in test_results:
        lcov_cmd.extend(['--add-tracefile', test_result.coverage_data_path])
    subprocess.check_call(lcov_cmd, stdout=DEV_NULL, stderr=DEV_NULL)
    return output_path


def main():
    args = ParseArgs()
    out_dir = OutDir(args)
    if not out_dir:
        sys.exit(
            'Couldn\'t find the output directory, pass --out-dir '
            '(absolute or relative to Fuchsia root) or set FUCHSIA_BUILD_DIR.')
    if not (distutils.spawn.find_executable(LCOV) and
            distutils.spawn.find_executable(GENHTML)):
        sys.exit('\'lcov\' and \'genhtml\' must be installed and in the PATH')
    host_tests_dir = os.path.join(out_dir, 'host_tests')
    test_patterns = args.test_patterns.split(',')
    test_paths = []
    for test_pattern in test_patterns:
        test_paths.extend(glob.glob(os.path.join(host_tests_dir, test_pattern)))
    thread_pool = ThreadPool()
    test_runner = TestRunner(out_dir)
    results_lists = thread_pool.map(test_runner.RunTest, test_paths)
    # flatten
    results = [result for sublist in results_lists for result in sublist]
    if not results:
        sys.exit('Found no dart tests that produced coverage data')
    for result in results:
        if result.exit_code:
            sys.exit('%s failed' % test_path)
    thread_pool.map(MakeRelativePathsAbsolute, results)
    combined_coverage_path = CombineCoverageData(results)
    subprocess.check_call(
        (
            GENHTML, combined_coverage_path, '--output-directory',
            args.report_dir),
        stdout=DEV_NULL,
        stderr=DEV_NULL)
    print(
        'Open file://%s to view the report' %
        os.path.join(os.path.abspath(args.report_dir), 'index.html'),
        file=sys.stderr)


if __name__ == '__main__':
    main()
