#!/usr/bin/env bash

srcdir=$1
builddir=$2
outputstem=$3  # optional
lcov=$4        # optional
genhtml=$5     # optional

if [[ -z "${srcdir}" ]]; then
    echo "xo-cmake-lcov-harness: expected non-empty srcdir"
    exit 1
fi

if [[ -z "${builddir}" ]]; then
    echo "xo-cmake-lcov-harness: expected non-empty builddir"
    exit 1
fi

if [[ -z ${outputstem} ]]; then
    outputstem=$builddir/ccov/out
fi

if [[ -z ${lcov} ]]; then
    lcov=@LCOV_EXECUTABLE@
    if [[ $lcov == "LCOV_EXECUTABLE-NOTFOUND" ]]; then
        echo "xo-cmake-lcov-harness: lcov executable not found during xo-cmake build/install"
        exit 1
    fi
fi

if [[ -z ${genhtml} ]]; then
    genhtml=@GENHTML_EXECUTABLE@
    if [[ $genhtml == "GENHTML_EXECUTABLE-NOTFOUND" ]]; then
        echo "xo-cmake-lcov-harness: genhtml executable not found during xo-cmake build/install"
        exit 1
    fi
fi

mkdir -p $builddir/ccov

# directory stems for location of {.gcda, gcno} coverage information,
#
# if we have source tree:
#
#   ${srcdir}
#   +- foo
#   |  \- foo.cpp
#   \- bar
#      \- quux
#         +- quux.cpp
#         \- quux_main.cpp
#
# then we expect build tree:
#
#   ${builddir}
#   +- foo
#   |  \- CMakeFiles
#   |     \- foo_target.dir
#   |        +- foo.cpp.gcda
#   |        \- foo.cpp.gcno
#   +- bar
#      \- quux
#         \- CMakeFiles
#            \- target4quux.dir
#               +- quux.cpp.gcda
#               +- quux.cpp.gcno
#               +- quux_main.cpp.gcda
#               \- quux_main.cpp.gcno
#
# in which case will have cmd_body:
#
#   ${primarydirs}
#      ./foo/CMakeFiles/foo_target.dir
#      ./bar/quux/CMakeFiles/target4quux.dir
#
# here foo_target, quux_target are whatever build is using for corresponding cmake target names.
#
# We want to invoke lcov like:
#
#   lcov --capture \
#        --output ${builddir}/ccov \
#        --exclude /utest/ \
#        --base-directory ${srcdir}/foo --directory ${builddir}/foo/CMakeFiles/foo_target.dir \
#        --base-directory ${srcdir}/bar/quux --directory ${builddir}/bar/quux/CMakeFiles/target4quux.dir
#
primarydirs=$(cd ${builddir} && find -name '*.gcno' \
                  | xargs --replace=xx dirname xx \
                  | uniq \
                  | sed -e 's:^\./::')

#echo "primarydirs=${primarydirs}"

cmd="${lcov} --output ${outputstem}.info --capture --ignore-errors source"

for bdir in ${primarydirs}; do
    sdir=$(dirname $(dirname ${bdir}))

    cmd="${cmd} --base-directory ${srcdir}/${sdir} --directory ${builddir}/${bdir}"
done

#echo cmd=${cmd}

set -x

# capture
${cmd}

# keep only files with paths under source tree
# (don't want coverage for external libraries such as libstdc++ etc)
${lcov} --extract ${outputstem}.info "${srcdir}/*" --output ${outputstem}2.info

# remove unit test dirs
# (we're interested in coverage of our installed code,  not of the unit tests that exercise it)
${lcov} --remove ${outputstem}2.info '*/utest/*' --output ${outputstem}3.info

# generate .html tree
mkdir -p ${builddir}/ccov/html
${genhtml} --ignore-errors source --show-details --prefix ${srcdir} --output-directory ${builddir}/ccov/html ${outputstem}3.info

# also send report to stdout
${lcov} --list ${outputstem}3.info
