#!/usr/bin/env python3
#
# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#

#
# Run the Coverity tool on the Trusted Firmware and produce a tarball ready to
# be submitted to Coverity Scan Online.
#

import sys
import argparse
import urllib.request
import tarfile
import os
import subprocess
import re

# local libraries
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "script", "tf-coverity")))
import utils
import coverity_tf_conf


def tarball_name(filename):
    "Isolate the tarball name without the filename's extension."
    # Handle a selection of "composite" extensions
    for ext in [".tar.gz", ".tar.bz2"]:
        if filename.endswith(ext):
            return filename[:-len(ext)]
    # For all other extensions, let the vanilla splitext() function handle it
    return os.path.splitext(filename)[0]

assert tarball_name("foo.gz") == "foo"
assert tarball_name("bar.tar.gz") == "bar"
assert tarball_name("baz.tar.bz2") == "baz"


def get_coverity_tool():
    coverity_tarball = "cov-analysis-linux64-2019.03.tar.gz"
    url = "http://files.oss.arm.com/downloads/tf-a/" + coverity_tarball
    print("Downloading Coverity Build tool from %s..." % url)
    file_handle = urllib.request.urlopen(url)
    output = open(coverity_tarball, "wb")
    output.write(file_handle.read())
    output.close()
    print("Download complete.")

    print("\nUnpacking tarball %s..." % coverity_tarball)
    tarfile.open(coverity_tarball).extractall()
    print("Tarball unpacked.")

    print("\nNow please load the Coverity tool in your PATH...")
    print("E.g.:")
    cov_dir_name = tarball_name(coverity_tarball)
    cov_dir_path = os.path.abspath(os.path.join(cov_dir_name, "bin"))
    print("  export PATH=%s$PATH" % (cov_dir_path + os.pathsep))

    # Patch is needed for coverity version 2019.03
    patch_file = os.path.abspath(os.path.join(__file__, os.pardir, "cov-2019.03-fix.patch"))
    cov_file = os.path.abspath(os.path.join(cov_dir_name, "config",
                               "templates", "gnu", "compiler-compat-arm-intrin.h"))
    print("Patching file")
    print(cov_file)
    utils.exec_prog("patch", [cov_file, "-i", patch_file],
                            out=subprocess.PIPE, out_text_mode=True)

def print_coverage(coverity_dir, tf_dir, exclude_paths=[], log_filename=None):
    analyzed = []
    not_analyzed = []
    excluded = []

    # Print the coverage report to a file (or stdout if no file is specified)
    if log_filename is not None:
        log_file = open(log_filename, "w")
    else:
        log_file = sys.stdout

    # Get the list of files analyzed by Coverity.
    #
    # To do that, we examine the build log file Coverity generated and look for
    # compilation lines. These are the lines starting with "COMPILING:" or
    # "EXECUTING:". We consider only those lines that actually compile C files,
    # i.e. lines of the form:
    #   gcc -c file.c -o file.o
    # This filters out other compilation lines like generation of dependency files
    # (*.d) and such.
    # We then extract the C filename.
    coverity_build_log = os.path.join(coverity_dir, "build-log.txt")
    with open(coverity_build_log, encoding="utf-8") as build_log:
        for line in build_log:
            line = re.sub('//','/', line)
            results = re.search("(?:COMPILING|EXECUTING):.*-o.*\.o .*-c (.*\.c)", line)
            if results is not None:
                filename = results.group(1)
                if filename not in analyzed:
                    analyzed.append(filename)

    # Now get the list of C files in the Trusted Firmware source tree.
    # Header files and assembly files are ignored, as well as anything that
    # matches the patterns list in the exclude_paths[] list.
    # Build a list of files that are in this source tree but were not analyzed
    # by comparing the 2 sets of files.
    all_files_count = 0
    old_cwd = os.path.abspath(os.curdir)
    os.chdir(tf_dir)
    git_process = utils.exec_prog("git", ["ls-files", "*.c"],
                                  out=subprocess.PIPE, out_text_mode=True)
    for filename in git_process.stdout:
        # Remove final \n in filename
        filename = filename.strip()

        # Expand to absolute path
        filename = os.path.abspath(filename)

        def is_excluded(filename, excludes):
            for pattern in excludes:
                if re.match(pattern[0], filename):
                    excluded.append((filename, pattern[1]))
                    return True
            return False

        if is_excluded(filename, exclude_paths):
            continue

        # Keep track of the number of C files in the source tree. Used to
        # compute the coverage percentage at the end.
        all_files_count += 1
        if filename not in analyzed:
            not_analyzed.append(filename)
    os.chdir(old_cwd)

    # Compute the coverage percentage
    # Note: The 1.0 factor here is used to make a float division instead of an
    # integer one.
    percentage = (1 - ((1.0 * len(not_analyzed) ) / all_files_count)) * 100

    #
    # Print a report
    #
    log_file.write("Files coverage: %d%%\n\n" % percentage)
    log_file.write("Analyzed %d files\n" % len(analyzed))

    if len(excluded) > 0:
        log_file.write("\n%d files were ignored on purpose:\n" % len(excluded))
        for exc in excluded:
            log_file.write(" - {0:50}   (Reason: {1})\n".format(exc[0], exc[1]))

    if len(analyzed) > 0:
        log_file.write("\n%d files analyzed:\n" % len(analyzed))
        for f in analyzed:
            log_file.write(" - %s\n" % f)

    if len(not_analyzed) > 0:
        log_file.write("\n%d files were not analyzed:\n" % len(not_analyzed))
        for f in not_analyzed:
            log_file.write(" - %s\n" % f)
        log_file.write("""
===============================================================================
Please investigate why the above files are not run through Coverity.

There are 2 possible reasons:

1) The build coverage is insufficient. Please review the tf-cov-make script to
   add the missing build config(s) that will involve the file in the build.

2) The file is expected to be ignored, for example because it is deprecated
   code. Please update the TF Coverity configuration to list the file and
   indicate the reason why it is safe to ignore it.
===============================================================================
""")
    log_file.close()


def parse_cmd_line(argv, prog_name):
    parser = argparse.ArgumentParser(
        prog=prog_name,
        description="Run Coverity on Trusted Firmware",
        epilog="""
        Please ensure the AArch64 & AArch32 cross-toolchains are loaded in your
        PATH. Ditto for the Coverity tools. If you don't have the latter then
        you can use the --get-coverity-tool to download them for you.
        """)
    parser.add_argument("--tf", default=None,
                        metavar="<Trusted Firmware source dir>",
                        help="Specify the location of ARM Trusted Firmware sources to analyze")
    parser.add_argument("--get-coverity-tool", default=False,
                        help="Download the Coverity build tool and exit",
                        action="store_true")
    parser.add_argument("--mode", choices=["offline", "online"], default="online",
                        help="Choose between online or offline mode for the analysis")
    parser.add_argument("--output", "-o",
                        help="Name of the output file containing the results of the analysis")
    parser.add_argument("--build-cmd", "-b",
                        help="Command used to build TF through Coverity")
    parser.add_argument("--analysis-profile", "-p",
                        action="append", nargs=1,
                        help="Analysis profile for a local analysis")
    args = parser.parse_args(argv)

    # Set a default name for the output file if none is provided.
    # If running in offline mode, this will be a text file;
    # If running in online mode, this will be a tarball name.
    if not args.output:
        if args.mode == "offline":
            args.output = "arm-tf-coverity-report.txt"
        else:
            args.output = "arm-tf-coverity-results.tgz"

    return args


if __name__ == "__main__":
    prog_name = sys.argv[0]
    args = parse_cmd_line(sys.argv[1:], prog_name)

    # If the user asked to download the Coverity build tool then just do that
    # and exit.
    if args.get_coverity_tool:
        # If running locally, use the commercial version of Coverity from the
        # EUHPC cluster.
        if args.mode == "offline":
            print("To load the Coverity tools, use the following command:")
            print("export PATH=/arm/tools/coverity/static-analysis/8.7.1/bin/:$PATH")
        else:
            get_coverity_tool()
        sys.exit(0)

    if args.tf is None:
        print("ERROR: Please specify the Trusted Firmware sources using the --tf option.",
              file=sys.stderr)
        sys.exit(1)

    # Get some important paths in the platform-ci scripts
    tf_root_dir = os.path.abspath(os.path.dirname(prog_name))

    if not args.build_cmd:
        args.build_cmd = os.path.join(tf_root_dir, "script", "tf-coverity", "tf-cov-make")

    run_coverity_script = os.path.join(tf_root_dir, "coverity", "run_coverity.sh")

    ret = subprocess.call([run_coverity_script, "check_tools", args.mode])
    if ret != 0:
        sys.exit(1)

    ret = subprocess.call([run_coverity_script, "configure"])
    if ret != 0:
        sys.exit(1)

    ret = subprocess.call([run_coverity_script, "build", args.build_cmd])
    if ret != 0:
        sys.exit(1)

    if args.mode == "online":
        ret = subprocess.call([run_coverity_script, "package", args.output])
    else:
        for profile in args.analysis_profile:
            ret = subprocess.call([run_coverity_script, "analyze",
                                   args.output,
                                   args.tf,
                                   profile[0]])
            if ret != 0:
                    break
    if ret != 0:
        print("An error occured (%d)." % ret, file=sys.stderr)
        sys.exit(ret)

    print("-----------------------------------------------------------------")
    print("Results can be found in file '%s'" % args.output)
    if args.mode == "online":
        print("This tarball can be uploaded at Coverity Scan Online:" )
        print("https://scan.coverity.com/projects/arm-software-arm-trusted-firmware/builds/new?tab=upload")
    print("-----------------------------------------------------------------")

    print_coverage("cov-int", args.tf, coverity_tf_conf.exclude_paths, "tf_coverage.log")
    with open("tf_coverage.log") as log_file:
        for line in log_file:
            print(line, end="")
