#!/bin/bash

. /dbld/functions.sh
DBLD_DIR=/dbld

YUM_INSTALL="yum install -y"
DNF_INSTALL="dnf install -y"
APT_INSTALL="apt-get install -y --no-install-recommends"

set -e
set -x

# this function is run first and is responsible for installing stuff that is
# needed by this script _before_ installing packages from packages.manifest.
#
# NOTE: If at all possible don't put anything here.
function install_dbld_dependencies()
{
    case "${OS_DISTRIBUTION}" in
        centos)
            $YUM_INSTALL wget yum-utils
            ;;
        debian|ubuntu)
            apt-get update
            $APT_INSTALL wget gnupg2
            if [ "${OS_DISTRIBUTION_CODE_NAME}" = "xenial" ]; then
                $APT_INSTALL -t xenial-backports debhelper dh-systemd
            fi
            ;;
        fedora)
            ;;
    esac
}

function install_cmake() {
    CMAKE_VERSION=3.12.2
    CMAKE_SHORT_VERSION=$(echo ${CMAKE_VERSION} | cut -d"." -f1-2)
    download_target "https://cmake.org/files/v${CMAKE_SHORT_VERSION}/cmake-${CMAKE_VERSION}-Linux-x86_64.sh" /tmp/cmake.sh
    chmod +x /tmp/cmake.sh
    mkdir -p /opt/cmake
    /tmp/cmake.sh --skip-license --prefix=/opt/cmake/
    ln -s /opt/cmake/bin/cmake /usr/bin/cmake
    rm -rf /tmp/cmake.sh
}

function install_criterion() {
    CRITERION_VERSION=2.3.3

    download_target "https://github.com/Snaipe/Criterion/releases/download/v${CRITERION_VERSION}/criterion-v${CRITERION_VERSION}.tar.bz2" /tmp/criterion.tar.bz2
    cd /tmp/
    tar xvf /tmp/criterion.tar.bz2
    cd /tmp/criterion-v${CRITERION_VERSION}
    cmake -DCMAKE_INSTALL_PREFIX=/usr .
    make install
    ldconfig
    rm -rf /tmp/criterion.tar.bz2 /tmp/criterion-v${CRITERION_VERSION}

}

function install_gosu() {
    GOSU_VERSION=1.10
    ARCHITECTURE=$1
    cat $DBLD_DIR/images/gosu.pubkey | gpg --import
    download_target "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-${ARCHITECTURE}" /usr/local/bin/gosu
    download_target "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-${ARCHITECTURE}.asc" /usr/local/bin/gosu.asc
    gpg --verify /usr/local/bin/gosu.asc
    rm /usr/local/bin/gosu.asc
    chmod +x /usr/local/bin/gosu
}

function install_gradle {
    GRADLE_VERSION=4.10
    download_target "https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip" /tmp/gradle.zip
    mkdir -p /opt/gradle
    unzip -d /opt/gradle /tmp/gradle.zip
    rm -rf /tmp/gradle.zip
    ln -s /opt/gradle/gradle-${GRADLE_VERSION}/bin/gradle /usr/bin/gradle
    find / -name 'libjvm.so' | sed 's@/libjvm.so@@g' | tee --append /etc/ld.so.conf.d/openjdk-libjvm.conf
    ldconfig
}

function install_pip2 {
    download_target "https://bootstrap.pypa.io/pip/2.7/get-pip.py" get-pip.py
    python2 get-pip.py
}

function download_target() {
    target=$1
    output=$2
    wget --no-check-certificate $target --output-document=$output
}

function filter_packages_by_platform {
    FILENAME=$1
    grep -v "#" ${FILENAME} | grep -e "${IMAGE_PLATFORM}" -e "${OS_DISTRIBUTION}[^-]" | cut -d"[" -f1
}

function add_copr_repo {

    # NOTE: we are removing dnf/yum plugins after enabling copr as they
    # install a couple of Python dependencies which then conflict with our
    # PIP installation later.
    case "${OS_DISTRIBUTION}" in
        centos)
            $YUM_INSTALL yum-plugin-copr
            yum copr enable -y czanik/syslog-ng-githead
            ;;
        fedora)
            $DNF_INSTALL -y dnf-plugins-core
            dnf copr enable -y czanik/syslog-ng-githead
            ;;
    esac
}

function add_epel_repo {
    $YUM_INSTALL epel-release
}

function install_apt_packages {
    apt-get update -qq -o Acquire::CompressionTypes::Order::=gz
    filter_packages_by_platform $DBLD_DIR/packages.manifest | xargs -t $APT_INSTALL --yes
}

function install_debian_build_deps {
    DEBIAN_CONTROL_FILE=$DBLD_DIR/extra-files/packaging-debian-control
    if ! [ -f ${DEBIAN_CONTROL_FILE} ]; then
        echo "install_debian_build_deps() called from dockerfile but without a Debian control file, make sure that control file is copied over to ${DEBIAN_CONTROL_FILE} by the prepare step"
        exit 1
    fi
    deb_run_build_command mk-build-deps -i ${DEBIAN_CONTROL_FILE} -t "apt-get -y -o Debug::pkgProblemResolver=yes --no-install-recommends"
}

function install_rpm_build_deps {
    RPM_SPEC_FILE=$DBLD_DIR/extra-files/syslog-ng.spec
    if ! [ -f ${RPM_SPEC_FILE} ]; then
        echo "install_rpm_build_deps() called from dockerfile but without a syslog-ng.spec file, make sure that control file is copied over to ${RPM_SPEC_FILE} by the prepare step"
        exit 1
    fi

    case "${OS_DISTRIBUTION}" in
        centos)
            rpm_run_build_command yum-builddep -y ${RPM_SPEC_FILE}
            ;;
        fedora)
            rpm_run_build_command dnf builddep -y ${RPM_SPEC_FILE}
            ;;
    esac
}

function install_yum_packages {
    $YUM_INSTALL findutils
    filter_packages_by_platform $DBLD_DIR/packages.manifest | xargs $YUM_INSTALL
}

function install_pip_packages {
    case "${IMAGE_PLATFORM}" in
        ubuntu-xenial|ubuntu-bionic)
            python_executables="python2"
            ;;
        debian-stretch|debian-buster)
            python_executables="python2"
            ;;
        devshell|kira)
            python_executables="python2 python3"
            ;;
        *)
            python_executables="python3"
            ;;
    esac
    for python_executable in ${python_executables}; do
        case "${IMAGE_PLATFORM}" in
            centos-7|ubuntu-xenial)
                $python_executable -m pip install --no-cache-dir --upgrade "pip < 21.0"
                $python_executable -m pip install --no-cache-dir --upgrade setuptools
                filter_packages_by_platform $DBLD_DIR/pip_packages.manifest | xargs $python_executable -m pip install --no-cache-dir --ignore-installed -U
                ;;
            kira|devshell)
                $python_executable -m pip install --no-cache-dir --upgrade pip
                $python_executable -m pip install --no-cache-dir --upgrade "setuptools < 58.0.0" # Remove the version limit when funcparserlib v1.0.0 is released
                filter_packages_by_platform $DBLD_DIR/pip_packages.manifest | xargs $python_executable -m pip install --no-cache-dir --ignore-installed -U
                ;;
            *)
                $python_executable -m pip install --no-cache-dir --upgrade pip
                $python_executable -m pip install --no-cache-dir --upgrade setuptools
                filter_packages_by_platform $DBLD_DIR/pip_packages.manifest | xargs $python_executable -m pip install --no-cache-dir --ignore-installed -U
                ;;
        esac
    done
}

function install_lsb_release {
    apt-get update && $APT_INSTALL lsb-release
}

function enable_dbgsyms {
    install_lsb_release
    case "${OS_DISTRIBUTION}" in
        ubuntu)
            echo "deb http://ddebs.ubuntu.com ${OS_DISTRIBUTION_CODE_NAME} main restricted universe multiverse" | tee -a /etc/apt/sources.list.d/ddebs.list
            echo "deb http://ddebs.ubuntu.com ${OS_DISTRIBUTION_CODE_NAME}-updates main restricted universe multiverse" | tee -a /etc/apt/sources.list.d/ddebs.list
            apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 428D7C01 C8CAB6595FDFF622
            ;;
        debian)
            echo "deb http://deb.debian.org/debian-debug/ ${OS_DISTRIBUTION_CODE_NAME}-debug main" | tee -a /etc/apt/sources.list
            echo "deb http://deb.debian.org/debian-debug/ ${OS_DISTRIBUTION_CODE_NAME}-proposed-updates-debug main" | tee -a /etc/apt/sources.list
            ;;
    esac
}

function install_perf {
    case "${OS_DISTRIBUTION}" in
        ubuntu)
            apt-cache search linux-tools | grep 'linux-tools-.*-generic' | cut -d" " -f1 | tail -n1 | cut -d"-" -f1-4 | xargs $APT_INSTALL
            ;;
    esac
}

function install_bison_from_source {
    BISON_VERSION=3.7.6
    cd /tmp
    wget https://ftp.gnu.org/gnu/bison/bison-${BISON_VERSION}.tar.gz
    tar xvfz bison-${BISON_VERSION}.tar.gz
    cd bison-${BISON_VERSION}
    ./configure --prefix=/usr/local --disable-nls
    make && make install
}

function fix_glib_atomic_warning {
    cat <<EOF | patch -d /usr/include/glib-2.0/  -p1
commit f304df34c7335526ef08701dc0b4a35f03299249
Author: Emmanuel Fleury <emmanuel.fleury@gmail.com>
Date:   Wed May 26 16:52:30 2021 +0200

    Coerce type cast to void* because it causes compiler warnings

    glib/gtestutils.c:4261:11: warning: incompatible pointer types passing 'gpointer *' (aka 'void **') to parameter of type 'GSList **' (aka 'struct _GSList **')
      while (!g_atomic_pointer_compare_and_exchange (test_filename_free_list, node->next, node));
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    glib/gatomic.h:215:44: note: expanded from macro 'g_atomic_pointer_compare_and_exchange'
        __atomic_compare_exchange_n ((atomic), &gapcae_oldval, (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \
                                               ^~~~~~~~~~~~~~

diff --git a/glib/gatomic.h b/glib/gatomic.h
index 5583fb0c9..5eba1dbc7 100644
--- a/glib/gatomic.h
+++ b/glib/gatomic.h
@@ -157,7 +157,7 @@ G_END_DECLS
     gint gaicae_oldval = (oldval);                                           \\
     G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint));                     \\
     (void) (0 ? *(atomic) ^ (newval) ^ (oldval) : 1);                        \\
-    __atomic_compare_exchange_n ((atomic), &gaicae_oldval, (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \\
+    __atomic_compare_exchange_n ((atomic), (void *) (&(gaicae_oldval)), (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \\
   }))
 #define g_atomic_int_add(atomic, val) \\
   (G_GNUC_EXTENSION ({                                                       \\
@@ -208,7 +208,7 @@ G_END_DECLS
     gpointer gapcae_oldval = (gpointer)(oldval);                             \\
     G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer));                 \\
     (void) (0 ? (gpointer) *(atomic) : NULL);                                \\
-    __atomic_compare_exchange_n ((atomic), &gapcae_oldval, (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \\
+    __atomic_compare_exchange_n ((atomic), (void *) (&(gapcae_oldval)), (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \\
   }))
 #endif /* defined(glib_typeof) */
 #define g_atomic_pointer_add(atomic, val) \\
EOF
}

# DO NOT REMOVE!
"$@"
