#!/usr/bin/perl
#==========================================================================
# testcoverage
#
# A script for launching the common use cases of gcovmerge.
#
# Usage: 
#
#     testcoverage [--with-package=PKG]          \
#                  [--trilinos-dir=PATH]         \
#                  [--build-dir=PATH]            \
#                  [--run-tests]                 \
#                  [--with-comm=[serial|mpi]]    \
#                  [--print-cmd]                 \
#                  [--with-report]               \
#                  [--with-report=PREFIX]        \
#                  [--help]
#
# This script should always be called from the build directory, which is 
# assumed to be a direct subdirectory of the Trilinos root directory.
# For example:
#   cd ~/Trilinos
#   cd BUILD_LINUX_MPI
#   ../testcoverage --with-packages=anasazi --run-tests
# 
# If no --with-packages options are specified, then it performs coverage 
# testing for for all of Trilinos, with a reporting breakdown by directory.
#
# Arguments:
#
#        --with-package=PKG
#            When specified, do not perform testing of all of Trilinos.
#            Instead, test the specified packages and report coverage
#            on a file-by-file basis.
#
#        --trilinos-dir=PATH
#            Absolute path to the Trilinos root directory. Required argument.
#            e.g., --trilinos-dir=/home/anyone/Trilinos-6.0
#
#        --build-dir=PATH
#            Path to the build dir, relative to the Trilinos root. 
#            Required argument.
#            e.g., --build-dir=LINUX_CODE_COV
#
#        --run-tests 
#            Run the test harness for the configured packages.
#
#        --with-comm=[serial|mpi]
#            Run test harness in serial or mpi (for use with --run-tests).
#            If unspecified, default is "serial"
#
#        --print-cmd
#            Print the commands before they issued. These will include the
#            calls to the test harness and the calls to gcovmerge.
#
#        --with-report
#        --with-report=PREFIX
#            Tells gcovmerge to generate line-by-line coverage reports for 
#            the source files. If --with-package flag is used, then
#            seperate HTML files are made, one for each package, where the
#            HTML file name is PREFIX followed by the package name. For example,
#            --with-report=mycov would generate filenames like "mycov_anasazi.html"
#            and "mycov_teuchos.html".
#            If PREFIX is not specified, the prefix "coverage_" is used.
#            When the --with-package flag is not specified, the --with-report option
#            is passed directly to gcovmerge.
#
#        Additional options are passed to gcovmerge. See documentation there.
#
# Written by Chris Baker (cgbaker@sandia.gov)   2005-08-01
#
#==========================================================================

# base options
use Cwd;
chomp($base = cwd);
@file_types = ("cpp", "c++", "c", "hpp", "h++", "h");
%source_files = ();
@pkg_list = ();

# parse command-line options
my $buildDir;
my $trilinosDir;
$source_directory = "../packages";
$runtests = 0;
$extra_args = ();
$print_cmd = 0;
$comm = "serial";
$category = "FRAMEWORK";
$gen_report = 0;
foreach (@ARGV){
    if(/--with-package=(.*)/){
        push @pkg_list, $1;
    }
    elsif(/--run-tests=(.*)/){
        $runtests = 1;
        $category = $1;
    }
    elsif(/--run-tests/){
        $runtests = 1;
    }
    elsif(/--trilinos-dir=(.*)/){
        $trilinosDir = $1;
    }
    elsif(/--build-dir=(.*)/){
        $buildDir = $1;
    }
    elsif(/--print-cmd/){
        $print_cmd = 1;
    }
    elsif(/--with-comm=(.*)/){
        $comm = $1;
    }
    elsif(/--with-report=(.*)/){
        $gen_report = 1;
        $report_prefix = $1;
    }
    elsif(/--with-report/){
        $gen_report = 1;        
    }
    elsif(/--help/){
        print "testcoverage - A Trilinos Code Coverage Utility\n";
        print "\n";
        print "Usage: \n";
        print "\n";
        print "    testcoverage [--with-package=PKG]          \\\n";
        print "                 [--trilinos-dir=PATH]         \\\n";
        print "                 [--build-dir=PATH]            \\\n";
        print "                 [--run-tests]                 \\\n";
        print "                 [--with-comm=[serial|mpi]]    \\\n";
        print "                 [--print-cmd]                 \\\n";
        print "                 [--help]\n";
        print "\n";
        print "Arguments:\n";
        print "\n";
        print "       --with-package=PKG\n";
        print "           When specified, do not perform testing of all of Trilinos.\n";
        print "           Instead, test the specified packages and report coverage\n";
        print "           on a file-by-file basis.\n";
        print "\n";
        print "       --trilinos-dir=PATH\n";
        print "           Absolute path to the Trilinos root directory. Required argument.\n";
        print "           e.g., --trilinos-dir=/home/anyone/Trilinos-6.0\n";
        print "\n";
        print "       --build-dir=PATH\n";
        print "           Path to the build dir, relative to the Trilinos root. \n";
        print "           Required argument.\n";
        print "           e.g., --build-dir=LINUX_CODE_COV\n";
        print "\n";
        print "       --run-tests \n";
        print "       --run-tests=CATEGORY \n";
        print "           Run the test harness for the configured packages. This runs tests of category CATEGORY, with a default of FRAMEWORK.\n";
        print "\n";
        print "       --with-comm=[serial|mpi]\n";
        print "           Run test harness in serial or mpi (for use with --run-tests).\n";
        print "           If unspecified, default is \"serial\"\n";
        print "\n";
        print "       --print-cmd\n";
        print "           Print the commands before they issued. These will include the\n";
        print "           calls to the test harness and the calls to gcovmerge.\n";
        print "\n";
        print "       --with-report\n";
        print "       --with-report=PREFIX\n";
        print "           Tells gcovmerge to generate line-by-line coverage reports for \n";
        print "           the source files. If --with-package flag is used, then\n";
        print "           seperate HTML files are made, one for each package, where the\n";
        print "           HTML file name is PREFIX followed by the package name. For example,\n";
        print "           --with-report=mycov would generate filenames like \"mycov_anasazi.html\"\n";
        print "           and \"mycov_teuchos.html\".\n";
        print "           If PREFIX is not specified, the prefix \"coverage_\" is used.\n";
        print "           When the --with-package flag is not specified, the --with-report option\n";
        print "           is passed directly to gcovmerge.\n";
        print "       --help\n";
        print "           Print this help output and exit.\n";
        print "\n";
        print "       Additional options are passed to gcovmerge. See documentation there.\n";
        print "\n";
        print "       See README.testcoverage for more help.\n";
        print "\n";

        exit;
    }
    else{ 
        $extra_args .= $_." ";
    }
}

if ($extra_args ne ""){
    print "\nArgs to gcovmerge: $extra_args\n";
}

# check for existance of trilinos-dir argument and actual directory
if (!$trilinosDir) {
    die "trilinos-dir value required\n";
} else {
    if (!stat($trilinosDir)) {
        die "cannot stat trilinos-dir: $trilinosDir\n";
    }
}

# check for existance of build-dir argument and actual directory
if (!$buildDir) {
    die "build-dir value required\n";
} else {
    if (!stat($buildDir)) {
        die "cannot stat build-dir: $buildDir\n";
    }
}

# run tests, if required
if ($runtests==1){
    print "\nRunning tests...\n";
    $cmd  = "$trilinosDir/commonTools/test/utilities/runtests";
    $cmd .= " --trilinos-dir=$trilinosDir --comm=$comm --build-dir=$buildDir --category=$category";
    if ($print_cmd) {
        print "Command: $cmd\n";
    }
    print "------------------------------------------------------------------------------\n";
    system($cmd);
}

# call gcovmerge
$numpkg = @pkg_list;
if ($numpkg == 0){
    # call gcovmerge for the whole of trilinos
    $cmd  = "$trilinosDir/commonTools/test/coverage/gcovmerge";
    if ($extra_args ne "") {
        $cmd .= " ".$extra_args;
    }
    $cmd .= " --exclude=test/ --exclude=/example/ --exclude=doc/ --exclude=util/ --exclude=ModalAnalysisSolvers/";
    $cmd .= " --without-files --with-directories-recursive";
    $cmd .= " --source-dir=$trilinosDir/packages";
    if ($gen_report){
        if (!defined($report_prefix)){
            $cmd .= " --with-report";
        }
        else {
            $cmd .= " --with-report=$report_prefix";
        }
    }
    $cmd .= " $buildDir";
    print "\nGenerating coverage information...\n";
    if ($print_cmd) {
        print "Command: $cmd\n";
    }
    print "------------------------------------------------------------------------------\n";
    system $cmd;
}
else {
    # call gcovmerge for the specified packages
    foreach (@pkg_list){
        $cmd  = "$trilinosDir/commonTools/test/coverage/gcovmerge";
        if ($extra_args ne "") {
            $cmd .= " ".$extra_args;
        }
        $cmd .= " --exclude=test/ --exclude=/example/ --exclude=doc/ --exclude=util/ --exclude=ModalAnalysisSolvers/";
        $cmd .= " --source-dir=$trilinosDir/packages/$_";
        if ($gen_report){
            if (!defined($report_prefix)){
                $cmd .= " --with-report=coverage_$_.html";
            }
            else {
                $cmd .= " --with-report=$report_prefix\_$_.html";
            }
        }
        $cmd .= " $buildDir";
        print "\nGenerating coverage information for package $_...\n";
        if ($print_cmd) {
            print "Command: $cmd\n";
        }
        print "------------------------------------------------------------------------------\n";
        system $cmd;
    }
}
print "\n";
