#!/usr/bin/env python
#
# Copyright 2018, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import argparse
import datetime
import logging
import json
import os
import shutil
import subprocess
import sys
import webbrowser

from run_host_unit_tests import *
"""
This script is used to generate code coverage results host supported libraries.
The script by default will generate an html report that summarizes the coverage
results of the specified tests. The results can also be browsed to provide a
report of which lines have been traveled upon execution of the binary.

NOTE: Code that is compiled out or hidden by a #DEFINE will be listed as
having been executed 0 times, thus reducing overall coverage.

The steps in order to add coverage support to a new library and its
corrisponding host test are as follows.

1. Add "clang_file_coverage" (defined in //build/Android.bp) as a default to the
   source library(s) you want statistics for.
   NOTE: Forgoing this default will cause no coverage data to be generated for
         the source files in the library.

2. Add "clang_coverage_bin" as a default to the host supported test binary that
   excercises the libraries that you covered in step 1.
   NOTE: Forgetting to add this will cause there to be *NO* coverage data
         generated when the binary is run.

3. Add the host test binary name and the files/directories you want coverage
   statistics for to the COVERAGE_TESTS variable defined below. You may add
   individual filenames or a directory to be tested.
   NOTE: Avoid using a / at the beginning of a covered_files entry as this
         breaks how the coverage generator resolves filenames.

TODO: Support generating XML data and printing results to standard out.
"""

COVERAGE_TESTS = [
    {
        "test_name": "net_test_avrcp",
        "covered_files": [
            "system/bt/profile/avrcp",
        ],
    },
    {
        "test_name": "bluetooth_test_sdp",
        "covered_files": [
            "system/bt/profile/sdp",
        ],
    },
    {
        "test_name": "test-vendor_test_host",
        "covered_files": [
            "system/bt/vendor_libs/test_vendor_lib/include",
            "system/bt/vendor_libs/test_vendor_lib/src",
        ],
    },
    {
        "test_name": "rootcanal-packets_test_host",
        "covered_files": [
            "system/bt/vendor_libs/test_vendor_lib/packets",
        ],
    },
    {
        "test_name": "bluetooth_test_common",
        "covered_files": [
            "system/bt/common",
        ],
    },
]

WORKING_DIR = '/tmp/coverage'
SOONG_UI_BASH = 'build/soong/soong_ui.bash'
LLVM_DIR = 'prebuilts/clang/host/linux-x86/clang-r353983b/bin'
LLVM_MERGE = LLVM_DIR + '/llvm-profdata'
LLVM_COV = LLVM_DIR + '/llvm-cov'


def write_root_html_head(f):
    # Write the header part of the root html file. This was pulled from the
    # page source of one of the generated html files.
    f.write("<!doctype html><html><head>" \
      "<meta name='viewport' content='width=device-width,initial-scale=1'><met" \
      "a charset='UTF-8'><link rel='stylesheet' type='text/css' href='style.cs" \
      "s'></head><body><h2>Coverage Report</h2><h4>Created: " +
      str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M')) +
      "</h4><p>Click <a href='http://clang.llvm.org/docs/SourceBasedCodeCovera" \
      "ge.html#interpreting-reports'>here</a> for information about interpreti" \
      "ng this report.</p><div class='centered'><table><tr><td class='column-e" \
      "ntry-bold'>Filename</td><td class='column-entry-bold'>Function Coverage" \
      "</td><td class='column-entry-bold'>Instantiation Coverage</td><td class" \
      "='column-entry-bold'>Line Coverage</td><td class='column-entry-bold'>Re" \
      "gion Coverage</td></tr>"
    )


def write_root_html_column(f, covered, count):
    percent = covered * 100.0 / count
    value = "%.2f%% (%d/%d) " % (percent, covered, count)
    color = 'column-entry-yellow'
    if percent == 100:
        color = 'column-entry-green'
    if percent < 80.0:
        color = 'column-entry-red'
    f.write("<td class=\'" + color + "\'><pre>" + value + "</pre></td>")


def write_root_html_rows(f, tests):
    totals = {
        "functions": {
            "covered": 0,
            "count": 0
        },
        "instantiations": {
            "covered": 0,
            "count": 0
        },
        "lines": {
            "covered": 0,
            "count": 0
        },
        "regions": {
            "covered": 0,
            "count": 0
        }
    }

    # Write the tests with their coverage summaries.
    for test in tests:
        test_name = test['test_name']
        covered_files = test['covered_files']
        json_results = generate_coverage_json(test)
        test_totals = json_results['data'][0]['totals']

        f.write("<tr class='light-row'><td><pre><a href=\'" + os.path.join(test_name, "index.html") + "\'>" +
                test_name + "</a></pre></td>")
        for field_name in ['functions', 'instantiations', 'lines', 'regions']:
            field = test_totals[field_name]
            totals[field_name]['covered'] += field['covered']
            totals[field_name]['count'] += field['count']
            write_root_html_column(f, field['covered'], field['count'])
        f.write("</tr>")

    #Write the totals row.
    f.write("<tr class='light-row-bold'><td><pre>Totals</a></pre></td>")
    for field_name in ['functions', 'instantiations', 'lines', 'regions']:
        field = totals[field_name]
        write_root_html_column(f, field['covered'], field['count'])
    f.write("</tr>")


def write_root_html_tail(f):
    # Pulled from the generated html coverage report.
    f.write("</table></div><h5>Generated by llvm-cov -- llvm version 7.0.2svn<" \
      "/h5></body></html>")


def generate_root_html(tests):
    # Copy the css file from one of the coverage reports.
    source_file = os.path.join(os.path.join(WORKING_DIR, tests[0]['test_name']), "style.css")
    dest_file = os.path.join(WORKING_DIR, "style.css")
    shutil.copy2(source_file, dest_file)

    # Write the root index.html file that sumarizes all the tests.
    f = open(os.path.join(WORKING_DIR, "index.html"), "w")
    write_root_html_head(f)
    write_root_html_rows(f, tests)
    write_root_html_tail(f)


def get_profraw_for_test(test_name):
    test_root = get_native_test_root_or_die()
    test_cmd = os.path.join(os.path.join(test_root, test_name), test_name)
    if not os.path.isfile(test_cmd):
        logging.error('The test ' + test_name + ' does not exist, please compile first')
        sys.exit(1)

    profraw_file_name = test_name + ".profraw"
    profraw_path = os.path.join(WORKING_DIR, os.path.join(test_name, profraw_file_name))
    llvm_env_var = "LLVM_PROFILE_FILE=\"" + profraw_path + "\""

    test_cmd = llvm_env_var + " " + test_cmd
    logging.info('Generating profraw data for ' + test_name)
    logging.debug('cmd: ' + test_cmd)
    if subprocess.call(test_cmd, shell=True) != 0:
        logging.error('Test ' + test_name + ' failed. Please fix the test before generating coverage.')
        sys.exit(1)

    if not os.path.isfile(profraw_path):
        logging.error(
            'Generating the profraw file failed. Did you remember to add the proper compiler flags to your build?')
        sys.exit(1)

    return profraw_file_name


def merge_profraw_data(test_name):
    cmd = []
    cmd.append(os.path.join(get_android_root_or_die(), LLVM_MERGE + " merge "))

    test_working_dir = os.path.join(WORKING_DIR, test_name)
    cmd.append(os.path.join(test_working_dir, test_name + ".profraw"))
    profdata_file = os.path.join(test_working_dir, test_name + ".profdata")

    cmd.append('-o ' + profdata_file)
    logging.info('Combining profraw files into profdata for ' + test_name)
    logging.debug('cmd: ' + " ".join(cmd))
    if subprocess.call(" ".join(cmd), shell=True) != 0:
        logging.error('Failed to merge profraw files for ' + test_name)
        sys.exit(1)


def generate_coverage_html(test):
    COVERAGE_ROOT = '/proc/self/cwd'

    test_name = test['test_name']
    file_list = test['covered_files']

    test_working_dir = os.path.join(WORKING_DIR, test_name)
    test_profdata_file = os.path.join(test_working_dir, test_name + ".profdata")

    cmd = [
        os.path.join(get_android_root_or_die(), LLVM_COV), "show", "-format=html", "-summary-only",
        "-show-line-counts-or-regions", "-show-instantiation-summary", "-instr-profile=" + test_profdata_file,
        "-path-equivalence=\"" + COVERAGE_ROOT + "\",\"" + get_android_root_or_die() + "\"",
        "-output-dir=" + test_working_dir
    ]

    # We have to have one object file not as an argument otherwise we can't specify source files.
    test_cmd = os.path.join(os.path.join(get_native_test_root_or_die(), test_name), test_name)
    cmd.append(test_cmd)

    # Filter out the specific files we want coverage for
    for filename in file_list:
        cmd.append(os.path.join(get_android_root_or_die(), filename))

    logging.info('Generating coverage report for ' + test['test_name'])
    logging.debug('cmd: ' + " ".join(cmd))
    if subprocess.call(" ".join(cmd), shell=True) != 0:
        logging.error('Failed to generate coverage for ' + test['test_name'])
        sys.exit(1)


def generate_coverage_json(test):
    COVERAGE_ROOT = '/proc/self/cwd'
    test_name = test['test_name']
    file_list = test['covered_files']

    test_working_dir = os.path.join(WORKING_DIR, test_name)
    test_profdata_file = os.path.join(test_working_dir, test_name + ".profdata")

    cmd = [
        os.path.join(get_android_root_or_die(), LLVM_COV),
        "export",
        "-summary-only",
        "-show-region-summary",
        "-instr-profile=" + test_profdata_file,
        "-path-equivalence=\"" + COVERAGE_ROOT + "\",\"" + get_android_root_or_die() + "\"",
    ]

    test_cmd = os.path.join(os.path.join(get_native_test_root_or_die(), test_name), test_name)
    cmd.append(test_cmd)

    # Filter out the specific files we want coverage for
    for filename in file_list:
        cmd.append(os.path.join(get_android_root_or_die(), filename))

    logging.info('Generating coverage json for ' + test['test_name'])
    logging.debug('cmd: ' + " ".join(cmd))

    json_str = subprocess.check_output(" ".join(cmd), shell=True)
    return json.loads(json_str)


def write_json_summary(test):
    test_name = test['test_name']
    test_working_dir = os.path.join(WORKING_DIR, test_name)
    test_json_summary_file = os.path.join(test_working_dir, test_name + '.json')
    logging.debug('Writing json summary file: ' + test_json_summary_file)
    json_file = open(test_json_summary_file, 'w')
    json.dump(generate_coverage_json(test), json_file)
    json_file.close()


def list_tests():
    for test in COVERAGE_TESTS:
        print "Test Name: " + test['test_name']
        print "Covered Files: "
        for covered_file in test['covered_files']:
            print "  " + covered_file
        print


def main():
    parser = argparse.ArgumentParser(description='Generate code coverage for enabled tests.')
    parser.add_argument(
        '-l',
        '--list-tests',
        action='store_true',
        dest='list_tests',
        help='List all the available tests to be run as well as covered files.')
    parser.add_argument(
      '-a', '--all',
      action='store_true',
      help='Runs all available tests and prints their outputs. If no tests ' \
           'are specified via the -t option all tests will be run.')
    parser.add_argument(
      '-t', '--test',
      dest='tests',
      action='append',
      type=str,
      metavar='TESTNAME',
      default=[],
      help='Specifies a test to be run. Multiple tests can be specified by ' \
           'using this option multiple times. ' \
           'Example: \"gen_coverage.py -t test1 -t test2\"')
    parser.add_argument(
      '-o', '--output',
      type=str,
      metavar='DIRECTORY',
      default='/tmp/coverage',
      help='Specifies the directory to store all files. The directory will be ' \
           'created if it does not exist. Default is \"/tmp/coverage\"')
    parser.add_argument(
        '-s',
        '--skip-html',
        dest='skip_html',
        action='store_true',
        help='Skip opening up the results of the coverage report in a browser.')
    parser.add_argument(
        '-j',
        '--json-file',
        dest='json_file',
        action='store_true',
        help='Write out summary results to json file in test directory.')

    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG, format='%(levelname)s %(message)s')
    logging.addLevelName(logging.DEBUG, "[\033[1;34m%s\033[0m]" % logging.getLevelName(logging.DEBUG))
    logging.addLevelName(logging.INFO, "[\033[1;34m%s\033[0m]" % logging.getLevelName(logging.INFO))
    logging.addLevelName(logging.WARNING, "[\033[1;31m%s\033[0m]" % logging.getLevelName(logging.WARNING))
    logging.addLevelName(logging.ERROR, "[\033[1;31m%s\033[0m]" % logging.getLevelName(logging.ERROR))

    args = parser.parse_args()
    logging.debug("Args: " + str(args))

    # Set the working directory
    global WORKING_DIR
    WORKING_DIR = os.path.abspath(args.output)
    logging.debug("Working Dir: " + WORKING_DIR)

    # Print out the list of tests then exit
    if args.list_tests:
        list_tests()
        sys.exit(0)

    # Check to see if a test was specified and if so only generate coverage for
    # that test.
    if len(args.tests) == 0:
        args.all = True

    tests_to_run = []
    for test in COVERAGE_TESTS:
        if args.all or test['test_name'] in args.tests:
            tests_to_run.append(test)
        if test['test_name'] in args.tests:
            args.tests.remove(test['test_name'])

    # Error if a test was specified but doesn't exist.
    if len(args.tests) != 0:
        for test_name in args.tests:
            logging.error('\"' + test_name + '\" was not found in the list of available tests.')
        sys.exit(1)

    # Generate the info for the tests
    for test in tests_to_run:
        logging.info('Getting coverage for ' + test['test_name'])
        get_profraw_for_test(test['test_name'])
        merge_profraw_data(test['test_name'])
        if args.json_file:
            write_json_summary(test)
        generate_coverage_html(test)

    # Generate the root index.html page that sumarizes all of the coverage reports.
    generate_root_html(tests_to_run)

    # Open the results in a browser.
    if not args.skip_html:
        webbrowser.open('file://' + os.path.join(WORKING_DIR, 'index.html'))


if __name__ == '__main__':
    main()
