#!/bin/bash
#
# Build the whole stack of releases for a given configuration
#
# The script also handles the legacy case where it is called with an additional
# version for dqm-common, but ignores that argument.
#

export GITROOT=${GITROOT:-https://gitlab.cern.ch/atlas-tdaq-software}

# The new default checkout and build location is $(pwd) and $(pwd)/build.
# This is equivalent to specifying the --here flag.
export CHECKOUT_AREA=${CHECKOUT_AREA:=$(pwd)}
export BUILD_AREA=${BUILD_AREA:=${CHECKOUT_AREA}/build}

CMAKE_TDAQ=$(dirname $(dirname $(readlink -f ${BASH_SOURCE[0]-$0})))
PATH=$(dirname $(readlink -f ${BASH_SOURCE[0]-$0})):$PATH

dry_run=0
# install_base=${CHECKOUT_AREA}

usage()
{
    echo
    echo "usage: $0 <options> <tdaq-common-version> <tdaq-version> <configuration> [ <cmake options> [ -- <ctest options> ]"
    echo
    echo " where <options> are:"
    echo
    echo "    --dry-run|-n         : do not execute, just show command lines to run by hand"
    echo "    --rpm                : build RPMs"
    echo "    --tar                : build tdaq-[common]-<version>-<configuration>.tar.gz files"
    echo "    --here               : checkout and build in current work dir (default)."
    echo "    --test               : use this script's cmake_tdaq dir (for testing new versions)"
    echo "    --checkout=<path>    : Override \${CHECKOUT_AREA} from environment"
    echo "    --build=<path>       : Override \${BUILD_AREA} from environment"
    echo "    --installbase=<path> : Change install base from \${CHECKOUT_AREA} to this"
    echo "    --variant=<name>     : Checkout and build a subset of packages and targets according to"
    echo "                             cmake/variants/<name>/packages.txt [optional]"
    echo "                             cmake/variants/<name>/prefix.cmake [optional]"
    echo "    --lcg=<lcg_version>  : expert option to overrule which LCG release is used to find compilers".
    echo "    --clean              : clean installed area before build"
    echo
    echo " <cmake_options> can be any CMake command line option or definition."
    echo
    echo "  The following options are handled in a special way by this script:"
    echo "    -D TDAQ_COMMON_VERSION=...  : numeric tdaq-common version (e.g. 4.2.1) to override"
    echo "     the version of the tdaq-common release that is built and installed."
    echo "    -D TDAQ_VERSION=...         : numeric tdaq version (e.g. 9.2.1) to override"
    echo "     the version of the tdaq release that is built and installed."
    echo
    echo "  Together these allow build a numbered release from the main branches without explicitly"
    echo "  modifying the CMakeLists.txt files."
    echo
    echo "  Other useful options:"
    echo
    echo "    -D TDAQ_NO_INSTALL_DEBUG=TRUE   : do not install the debug symbols to reduce size"
    echo "    -D USE_CCACHE=TRUE              : use ccache to speed up build."
    echo "    -D LCG_VERSION_CONFIG=<version> : overwrite LCG release version."
    echo "     a <version> of the farm LCG_999<path> will use the LCG nightly builds, e.g."
    echo         LCG_999dev4/Tue - use dev4 nightly from last Tuesday
    echo
    echo " <ctest options> are options passed to the CTest driver script."
    echo
    echo "   -D CTEST_NOCLEAN=TRUE : do not clean an existing build directory - don't use if absolutely sure."
    echo "   -D CTEST_NOTESTS=TRUE : do not run the unit tests."
    echo "   -D CTEST_NO_SUBMIT=TRUE : do not submit test results - use this outside of CERN."
    echo
    echo
    echo " Examples: "
    echo
    echo " % build_stack tdaq-common-99-00-00 tdaq-99-00-00 x86_64-centos7-gcc8-opt"
    echo "   will build the latest nightly release for the given configuration."
}

pass_opts=

while [ $# -gt 0 ]
do
    case $1 in
        --rpm)
            pass_opts="${pass_opts} --rpm"
            shift
            ;;
        --tar)
            pass_opts="${pass_opts} --tar"
            shift
            ;;
        --help|-h)
            usage
            exit 0
            ;;
        --installbase=*)
            install_base=${1#--installbase=}
            shift
            ;;
        --checkout=*)
            CHECKOUT_AREA=${1#--checkout=}
            pass_opts="${pass_opts} $1"
            shift
            ;;
        --build=*)
            BUILD_AREA=${1#--build=}
            pass_opts="${pass_opts} $1"
            shift
            ;;
        --here)
            CHECKOUT_AREA=$(pwd)
            BUILD_AREA=${CHECKOUT_AREA}/build
            shift
            ;;
        --clean)
            pass_opts="${pass_opts} $1"
            shift
            ;;
        --package-file-tdaq-common=*)
            pass_opts_tdaq_common="--package-file=${1#--package-file-tdaq-common=}"
            shift
            ;;
        --package-file-tdaq=*)
            pass_opts_tdaq="--package-file=${1#--package-file-tdaq=}"
            shift
            ;;
        --variant=*)
            pass_opts="${pass_opts} $1"
            shift
            ;;
        --lcg=*)
            pass_opts="${pass_opts} $1"
            shift
            ;;
        --test)
            TEST_MODE=1
            shift
            ;;
        --dry-run|-n)
            dry_run=1
            shift
            ;;
        -*)
            echo "Invalid option: $1" 1>&2
            exit 1
            ;;
        *)
            break
            ;;
    esac
done

if [ $# -lt 3 ]; then
    usage
    exit 1
fi

if [ -z "${install_base}" ]; then
    export CMAKE_PROJECT_PATH=${CHECKOUT_AREA}
    install_base=${CHECKOUT_AREA}
else
    export CMAKE_PROJECT_PATH=${install_base}
fi

# source area must exist, or we must be allowed to create it
[ -d ${CHECKOUT_AREA} ] || mkdir -p ${CHECKOUT_AREA} && [ -w ${CHECKOUT_AREA}/. ] || { echo "Cannot write to checkout area: ${CHECKOUT_AREA}"; exit 2; }

# we must have write access to the build area
mkdir -p ${BUILD_AREA} || exit 2
[ -w ${BUILD_AREA}/. ] || { echo "Cannot write to build area: ${BUILD_AREA}"; exit 2; }

tdaq_common=$1

case "$2" in
    dqm-common-*)
        # ignore this argument
        echo "The dqm-common version is no longer needed and can be removed from the command line"
        shift
        ;;
    *)
        ;;
esac

tdaq=$2
config=$3

shift 3

if [ -z "${TEST_MODE}" ]; then
    CMAKE_TDAQ=$(mktemp -d)/cmake_tdaq
    trap "rm -rf $(dirname ${CMAKE_TDAQ})" EXIT
    CMAKE_TDAQ_VERSION=$(tagpkg -l cmake_tdaq ${tdaq_common} | awk '{ print $2; }')
    git clone -q ${GITROOT}/cmake_tdaq.git ${CMAKE_TDAQ} || exit 1
    (cd ${CMAKE_TDAQ} && git checkout -q ${CMAKE_TDAQ_VERSION}) || exit 1
fi

for arg in $@
do
    case "${arg}" in
        -DTDAQ_COMMON_VERSION=*)
            tdaq_common_install=${install_base}/tdaq-common/tdaq-common-$(printf "%02d-%02d-%02d" $(echo "${arg#-DTDAQ_COMMON_VERSION=}" | tr '.' ' '))/installed
            EXTRA_ARGS_TDAQ_COMMON="-DCMAKE_INSTALL_PREFIX=${tdaq_common_install}"
            ;;
        TDAQ_COMMON_VERSION=*)
            tdaq_common_install=${install_base}/tdaq-common/tdaq-common-$(printf "%02d-%02d-%02d" $(echo "${arg#TDAQ_COMMON_VERSION=}" | tr '.' ' '))/installed
            EXTRA_ARGS_TDAQ_COMMON="-DCMAKE_INSTALL_PREFIX=${tdaq_common_install}"
            ;;
        -DTDAQ_VERSION=*)
            tdaq_install=${install_base}/tdaq/tdaq-$(printf "%02d-%02d-%02d" $(echo "${arg#-DTDAQ_VERSION=}" | tr '.' ' '))/installed
            EXTRA_ARGS_TDAQ="-DCMAKE_INSTALL_PREFIX=${tdaq_install}"
            ;;
        TDAQ_VERSION=*)
            tdaq_install=${install_base}/tdaq/tdaq-$(printf "%02d-%02d-%02d" $(echo "${arg#TDAQ_VERSION=}" | tr '.' ' '))/installed
            EXTRA_ARGS_TDAQ="-DCMAKE_INSTALL_PREFIX=${tdaq_install}"
            ;;
        *)
            ;;
    esac
done

if [ ${dry_run} -eq 1 ]
then
    echo export CMAKE_PROJECT_PATH=${CMAKE_PROJECT_PATH}
    echo export CHECKOUT_AREA=${CHECKOUT_AREA}
    echo export BUILD_AREA=${BUILD_AREA}
    echo ${CMAKE_TDAQ}/bin/build_release  ${pass_opts} ${pass_opts_tdaq_common} tdaq-common ${tdaq_common} ${config} ${EXTRA_ARGS_TDAQ_COMMON} $@
    echo ${CMAKE_TDAQ}/bin/build_release ${pass_opts} ${pass_opts_tdaq} tdaq ${tdaq} ${config} ${EXTRA_ARGS_TDAQ} $@
else
    ${CMAKE_TDAQ}/bin/build_release ${pass_opts} ${pass_opts_tdaq_common} tdaq-common ${tdaq_common} ${config} ${EXTRA_ARGS_TDAQ_COMMON} $@
    ${CMAKE_TDAQ}/bin/build_release ${pass_opts} ${pass_opts_tdaq} tdaq ${tdaq} ${config} ${EXTRA_ARGS_TDAQ} $@
fi
