#!/usr/bin/env bash

# If you have "no space left" error, you can change the location of temporary files with BUILDPLACE environment variable.

# Advanced usage:
# Test gcc-9:
# env DIST=disco EXTRAPACKAGES="gcc-9 g++-9" DEB_CC=gcc-9 DEB_CXX=g++-9 CMAKE_FLAGS=" -DNO_WERROR=1 " ./release
# Test gcc-8:
# env DIST=bionic EXTRAPACKAGES="gcc-8 g++-8" DEB_CC=gcc-8 DEB_CXX=g++-8 CMAKE_FLAGS=" -DNO_WERROR=1 " ./release
# Clang6 build:
# env DIST=bionic EXTRAPACKAGES="clang-6.0 libstdc++-8-dev lld-6.0 liblld-6.0-dev libclang-6.0-dev liblld-6.0" DEB_CC=clang-6.0 DEB_CXX=clang++-6.0 CMAKE_FLAGS=" -DNO_WERROR=1 " ./release
# Clang7 build:
# env DIST=unstable EXTRAPACKAGES="clang-7 libstdc++-8-dev lld-7 liblld-7-dev libclang-7-dev liblld-7" DEB_CC=clang-7 DEB_CXX=clang++-7 CMAKE_FLAGS=" -DNO_WERROR=1 " ./release
# Clang6 without internal compiler (for low memory arm64):
# env DIST=bionic DISABLE_PARALLEL=1 EXTRAPACKAGES="clang-6.0 libstdc++-8-dev" DEB_CC=clang-6.0 DEB_CXX=clang++-6.0 CMAKE_FLAGS=" -DNO_WERROR=1 " ./release
# Do not compile internal compiler but use from system:
# env CMAKE_FLAGS="-DUSE_INTERNAL_LLVM_LIBRARY=0 -DENABLE_EMBEDDED_COMPILER=0 -DINTERNAL_COMPILER_EXECUTABLE=clang-6.0 -DINTERNAL_LINKER_EXECUTABLE=ld.lld-6.0 -DINTERNAL_COMPILER_BIN_ROOT=/usr/bin/" EXTRAPACKAGES="clang-6.0 lld-6.0 libstdc++-8-dev" DEB_CXX=clang++-6.0 DEB_CC=clang-6.0 TEST_RUN=1 TEST_OPT="compile" ./release

# Build with ASan:
# env SANITIZER=address ./release

# Version increment:
# Default release: 18.1.2 -> 18.2.0:
# ./release --version
# or
# ./release --version minor
# Bugfix release (only with small patches to previous release): 18.1.2 -> 18.1.3:
# ./release --version patch
# Do this once per year: 18.1.2 -> 19.0.0:
# ./release --version major

set -e

CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
cd $CUR_DIR

source "./utils/release/release_lib.sh"

PBUILDER_AUTOUPDATE=${PBUILDER_AUTOUPDATE=4320}

DEBUILD_NOSIGN_OPTIONS="-us -uc"
DEBUILD_NODEPS_OPTIONS="-d"
USE_PBUILDER=${USE_PBUILDER=1}

if [ -z "$VERSION_STRING" ] ; then
    get_revision_author
fi

while [[ $1 == --* ]]
do
    if [[ $1 == '--test' ]]; then
        TEST='yes'
        VERSION_POSTFIX+=+test
        shift
    elif [[ $1 == '--check-build-dependencies' ]]; then
        DEBUILD_NODEPS_OPTIONS=""
        shift
    elif [[ $1 == '--version' ]]; then
        gen_revision_author $2
        exit 0
    elif [[ $1 == '--pbuilder' ]]; then
        # Default
        shift
    elif [[ $1 == '--no-pbuilder' ]]; then
        USE_PBUILDER=
        shift
    elif [[ $1 == '--fast' ]]; then
        # Wrong but fast pbuilder mode: create base package with all depends
        EXTRAPACKAGES="$EXTRAPACKAGES debhelper cmake ninja-build gcc-8 g++-8 libc6-dev libicu-dev libreadline-dev psmisc bash expect python3 python3-lxml python3-termcolor python3-requests curl perl sudo openssl netcat-openbsd"
        shift
    elif [[ $1 == '--rpm' ]]; then
        MAKE_RPM=1
        shift
    elif [[ $1 == '--tgz' ]]; then
        MAKE_TGZ=1
        shift
    else
        echo "Unknown option $1"
        exit 2
    fi
done

# Build options
if [ -n "$SANITIZER" ]
then
    if [[ "$SANITIZER" == "address" ]]; then VERSION_POSTFIX+="+asan"
    elif [[ "$SANITIZER" == "thread" ]]; then VERSION_POSTFIX+="+tsan"
    elif [[ "$SANITIZER" == "memory" ]]; then VERSION_POSTFIX+="+msan"
    elif [[ "$SANITIZER" == "undefined" ]]; then VERSION_POSTFIX+="+ubsan"
    elif [[ "$SANITIZER" == "libfuzzer" ]]; then
        VERSION_POSTFIX+="+libfuzzer"
        MALLOC_OPTS="-DENABLE_TCMALLOC=0 -DENABLE_JEMALLOC=0"
    else
        echo "Unknown value of SANITIZER variable: $SANITIZER"
        exit 3
    fi

    export DEB_CC=${DEB_CC=clang-10}
    export DEB_CXX=${DEB_CXX=clang++-10}
    EXTRAPACKAGES="$EXTRAPACKAGES clang-10 lld-10"
elif [[ $BUILD_TYPE == 'valgrind' ]]; then
    MALLOC_OPTS="-DENABLE_TCMALLOC=0 -DENABLE_JEMALLOC=0"
    VERSION_POSTFIX+="+valgrind"
elif [[ $BUILD_TYPE == 'debug' ]]; then
    CMAKE_BUILD_TYPE=Debug
    VERSION_POSTFIX+="+debug"
fi

CMAKE_FLAGS=" $MALLOC_OPTS -DSANITIZE=$SANITIZER -DENABLE_CHECK_HEAVY_BUILDS=1 $CMAKE_FLAGS"
[[ -n "$CMAKE_BUILD_TYPE" ]] && CMAKE_FLAGS=" -DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE $CMAKE_FLAGS"

export CMAKE_FLAGS
export EXTRAPACKAGES

VERSION_STRING+=$VERSION_POSTFIX
echo -e "\nCurrent version is $VERSION_STRING"

if [ -z "$NO_BUILD" ] ; then
    gen_changelog "$VERSION_STRING" "" "$AUTHOR" ""
    if [ -z "$USE_PBUILDER" ] ; then
        DEB_CC=${DEB_CC:=`which gcc-10 gcc-9 gcc | head -n1`}
        DEB_CXX=${DEB_CXX:=`which gcc-10 g++-9 g++ | head -n1`}
        # Build (only binary packages).
        debuild --preserve-env -e PATH \
        -e DEB_CC=$DEB_CC -e DEB_CXX=$DEB_CXX -e CMAKE_FLAGS="$CMAKE_FLAGS" \
        -b ${DEBUILD_NOSIGN_OPTIONS} ${DEBUILD_NODEPS_OPTIONS}
    else
        export DIST=${DIST:=bionic}
        export SET_BUILDRESULT=${SET_BUILDRESULT:=$CUR_DIR/..}

        if [[ -z `which pbuilder` ]] ; then
            sudo apt install -y pbuilder devscripts ccache fakeroot debhelper debian-archive-keyring debian-keyring lsb-release
        fi

        . $CUR_DIR/debian/.pbuilderrc

        if [[ ! -e "/usr/share/debootstrap/scripts/${DIST}" ]] ; then
            sudo ln -s gutsy /usr/share/debootstrap/scripts/${DIST}
        fi

        if [[ -n "$FORCE_PBUILDER_CREATE" || ! -e "$BASETGZ" ]] ; then
            echo Creating base system $BASETGZ
            [ ! -e "/usr/share/debootstrap/scripts/${DIST}" ] && sudo ln -s gutsy /usr/share/debootstrap/scripts/${DIST}
            sudo --preserve-env bash -x pbuilder create --configfile $CUR_DIR/debian/.pbuilderrc $PBUILDER_OPT
        fi

        if [ "$PBUILDER_AUTOUPDATE" -gt 0 ]; then
            # Update every 3 days (60*24*3 minutes)
            if [[ -n "$PBUILDER_UPDATE" ]] || test `find "$BASETGZ" -mmin +$PBUILDER_AUTOUPDATE` ; then
                echo Updating base system $BASETGZ
                sudo --preserve-env pbuilder update --configfile $CUR_DIR/debian/.pbuilderrc $PBUILDER_OPT
            fi
        fi

        pdebuild --configfile $CUR_DIR/debian/.pbuilderrc -- $PBUILDER_OPT
    fi
fi

if [ -n "$MAKE_RPM" ]; then
    make_rpm
fi

if [ -n "$MAKE_TGZ" ]; then
    make_tgz
fi