#!/bin/bash

die() { echo "ABORT: $*"; exit 1; }

TARGET=${CARGO_TARGET_DIR:-./target}

# This same script is called back with "run-test" argument by
# run-all-feature-comb.pl
case "$1" in
    run-test)
        # Depending on the Rust version, test executables may be
        # dumped in $TARGET/debug or $TARGET/debug/deps
        rm -r $(find $TARGET/debug -name "stakker-*") >/dev/null 2>&1

        # Can't use --no-run because it excludes some of the tests.
        # Need "link-dead-code" to get all the source (including
        # source without coverage) to show up.  Need "opt-level=0" or
        # otherwise "link-dead-code" fails with linking problems.
        RUSTFLAGS="-C link-dead-code -C codegen-units=1 -C opt-level=0" \
                 cargo test --no-default-features --features "$2" >kcov/test-$$ 2>&1 ||
            die "cargo test failed; see kcov/test-$$"
        rm kcov/test-$$

        set ""
        set $(find $TARGET/debug -name "stakker-*" -type f -executable)
        #was: ls $TARGET/debug/stakker-* | egrep 'stakker-[A-Fa-f0-9]+$'

        [ -z "$1" ] && die "Can't find test binary in $TARGET/debug"
        [ ! -z "$2" ] && die "Found more than one test binary in $TARGET/debug"
        EXE="$1"

        TESTS=$(echo $(find src -name "*.rs" | fgrep /test | fgrep -v macro_coverage) | perl -pe 's/ /,/g')

        mkdir kcov/out-$$
        kcov --verify \
             --include-pattern=stakker/src \
             --exclude-pattern=$TESTS \
             kcov/out-$$ $EXE ||
            die "kcov failed"
        exit 0;;
    "") ;;
    *) die "Invalid argument";;
esac


# Check macro.rs COVERAGE tags
perl -e '
die unless open IN, "<src/macros.rs";
my %tags = ();
while (<IN>) {
    if (/COVERAGE\!\((.*?)\)/) {
        die "Duplicate COVERAGE tag: $1" if exists $tags{$1};
        $tags{$1} = 1;
    }
}
die unless close IN;
print((0 + keys %tags) . " macro.rs COVERAGE tags\n");
die unless open IN, "<src/test/macro_coverage.rs";
while (<IN>) {
    if (/pub\s+fn\s+(\S*?)\(\)/) {
        delete $tags{$1};
    }
}
exit 0 if 0 == keys %tags;
print "Coverage tag without entry in macro_coverage.rs: $_" for keys %tags;
exit 1;
' || die COVERAGE tag problem


# Run test with all feature combinations
rm -r kcov >/dev/null 2>&1
mkdir kcov || die "Can't creat kcov/"

./run-all-feature-comb.pl $0 run-test

echo "=== MERGING reports to kcov/out/ ..."
mkdir kcov/out
kcov --merge kcov/out kcov/out-*

# Check that no files have been excluded.  Skip src/lib.rs, because
# there is no executable code in it.
( find src -name "*.rs" |
      fgrep -v test |
      perl -pe 's|.*/||';
  echo macro_coverage.rs;  # Always include this
) | sort >kcov/list-source
ls kcov/out/kcov-merged/*.rs.*.html |
    perl -pe 's/\.rs.*/.rs/; s|.*/||;' |
    sort >kcov/list-covered
cmp kcov/list-source kcov/list-covered >/dev/null 2>&1 || {
    echo "WARNING: Some files not included in report:" $(comm -23 kcov/list-source kcov/list-covered)
}
