#!/bin/bash
# Exit on any error
set -e

# HTConder version
HTCONDOR_VERSION=$1
echo "HTCondor version is $HTCONDOR_VERSION"

# shellcheck disable=SC2206 # don't have to worry abour word splitting
AVERSION=(${HTCONDOR_VERSION//./ })
MAJOR_VER=${AVERSION[0]}
MINOR_VER=${AVERSION[1]}
if [ "$MINOR_VER" -eq 0 ]; then
    REPO_VERSION=$MAJOR_VER.0
else
    REPO_VERSION=$MAJOR_VER.x
fi

# Platform variables
VERSION_CODENAME='none'
. /etc/os-release
echo "Building on $NAME $VERSION"
VERSION_ID=${VERSION_ID%%.*}
ARCH=$(arch)
REPO_ARCH='noarch'

# We need this RPM macro to tell SLES apart for openSUSE
if [ -d /etc/rpm ]; then
    echo "%os_release_id $ID" > /etc/rpm/macros.os-release-id
fi

# Early versions of AlmaLinux did not properly override rpm-macros for x86_64-v2
if [ "$ID" = 'almalinux' ]; then
    if rpm -qf /bin/sh | grep -q 'x86_64_v2'; then
        ARCH='x86_64_v2'
        REPO_ARCH='x86_64_v2'
        echo '%__cflags_arch_x86_64_level -v2' > /etc/rpm/macros.gcc-arch-level-v2
    fi
fi

echo "ID=$ID VERSION_ID=$VERSION_ID VERSION_CODENAME=$VERSION_CODENAME ARCH=$ARCH"

if [ "$ID" = 'debian' ] || [ "$ID" = 'ubuntu' ]; then
    SUDO_GROUP='sudo'
else
    SUDO_GROUP='wheel'
fi

if [ "$ID" = 'debian' ] || [ "$ID" = 'ubuntu' ]; then
    export DEBIAN_FRONTEND='noninteractive'
    apt-get update --yes
    apt-get upgrade --yes
    INSTALL='apt-get install --yes'
elif [ "$ID" = 'centos' ]; then
    yum upgrade --assumeyes
    INSTALL='yum install --assumeyes'
elif [ "$ID" = 'opensuse-leap' ] || [ "$ID" = 'sles' ]; then
    zypper --non-interactive update
    INSTALL='zypper --non-interactive install'
    # Work around for broken openSUSE 16.0 Docker image
    # $INSTALL --oldpackage libsqlite3-0=3.51.3-160000.1.1
    $INSTALL system-group-wheel system-user-mail
elif [ "$ID" = 'amzn' ] || [ "$ID" = 'almalinux' ] || [ "$ID" = 'fedora' ]; then
    dnf upgrade --assumeyes
    INSTALL='dnf install --assumeyes'
    $INSTALL 'dnf-command(config-manager)'
fi

if [ "$ID" = 'amzn' ]; then
    $INSTALL -y shadow-utils
fi

# Add users that might be used in CHTC
# The HTCondor that runs inside the container needs to have the user defined
for i in {1..161}; do
    uid=$((i+5000));
    useradd --uid  $uid --gid $SUDO_GROUP --shell /bin/bash --create-home "slot$i";
done

for i in {1..161}; do
    uid=$((i+5299));
    useradd --uid  $uid --gid $SUDO_GROUP --shell /bin/bash --create-home "slot1_$i";
done

useradd --uid  6004 --gid $SUDO_GROUP --shell /bin/bash --create-home condorauto
useradd --uid  4977 --gid $SUDO_GROUP --shell /bin/bash --create-home condorbuilder
useradd --uid 20343 --gid $SUDO_GROUP --shell /bin/bash --create-home blin
useradd --uid 24200 --gid $SUDO_GROUP --shell /bin/bash --create-home cabollig
useradd --uid 20006 --gid $SUDO_GROUP --shell /bin/bash --create-home gthain
useradd --uid 20007 --gid $SUDO_GROUP --shell /bin/bash --create-home jfrey
useradd --uid 20018 --gid $SUDO_GROUP --shell /bin/bash --create-home johnkn
useradd --uid 20020 --gid $SUDO_GROUP --shell /bin/bash --create-home matyas
useradd --uid 20013 --gid $SUDO_GROUP --shell /bin/bash --create-home tannenba
useradd --uid 20345 --gid $SUDO_GROUP --shell /bin/bash --create-home tim
useradd --uid 20015 --gid $SUDO_GROUP --shell /bin/bash --create-home tlmiller
useradd --uid 25197 --gid $SUDO_GROUP --shell /bin/bash --create-home westphall

# Provide a condor_config.generic
mkdir -p /usr/local/condor/etc/examples
echo 'use SECURITY : HOST_BASED' > /usr/local/condor/etc/examples/condor_config.generic

if [ "$ID" = 'almalinux' ] || [ "$ID" = 'centos' ]; then
    $INSTALL epel-release
    if [ "$VERSION_ID" -eq 7 ]; then
        $INSTALL centos-release-scl
    elif [ "$VERSION_ID" -eq 8 ]; then
        dnf config-manager --set-enabled powertools
    elif [ "$VERSION_ID" -eq 9 ] || [ "$VERSION_ID" -eq 10 ]; then
        dnf config-manager --set-enabled crb
    fi
fi

# Setup RPM based repositories (include alpha repositories)
if [ "$ID" = 'amzn' ]; then
    $INSTALL "https://htcss-downloads.chtc.wisc.edu/repo/$REPO_VERSION/htcondor-release-current.amzn$VERSION_ID.$REPO_ARCH.rpm"
    sed -i s/enabled=0/enabled=1/ /etc/yum.repos.d/htcondor-alpha.repo
fi

if [ "$ID" = 'almalinux' ] || [ "$ID" = 'centos' ]; then
    $INSTALL "https://htcss-downloads.chtc.wisc.edu/repo/$REPO_VERSION/htcondor-release-current.el$VERSION_ID.$REPO_ARCH.rpm"
    sed -i s/enabled=0/enabled=1/ /etc/yum.repos.d/htcondor-alpha.repo
fi

if [ "$ID" = 'fedora' ]; then
    $INSTALL "https://htcss-downloads.chtc.wisc.edu/repo/$REPO_VERSION/htcondor-release-current.fc$VERSION_ID.$REPO_ARCH.rpm"
    sed -i s/enabled=0/enabled=1/ /etc/yum.repos.d/htcondor-alpha.repo
fi

# openSUSE has a zypper command to install a repo from a URL.
# Let's use that in the future. This works for now.
if [ "$ID" = 'opensuse-leap' ]; then
    zypper --non-interactive --no-gpg-checks install "https://htcss-downloads.chtc.wisc.edu/repo/$REPO_VERSION/htcondor-release-current.leap$VERSION_ID.$REPO_ARCH.rpm"
    sed -i s/enabled=0/enabled=1/ /etc/zypp/repos.d/htcondor-alpha.repo
    for key in /etc/pki/rpm-gpg/*; do
        rpmkeys --import "$key"
    done
fi

if [ "$ID" = 'sles' ]; then
    # Hard code version in this special case
    zypper --non-interactive --no-gpg-checks install "https://htcss-downloads.chtc.wisc.edu/repo/$REPO_VERSION/htcondor-release-current.sles15sp5.$REPO_ARCH.rpm"
    sed -i s/enabled=0/enabled=1/ /etc/zypp/repos.d/htcondor-alpha.repo
    for key in /etc/pki/rpm-gpg/*; do
        rpmkeys --import "$key"
    done
fi

# Setup Debian based repositories
if [ "$ID" = 'debian' ] || [ "$ID" = 'ubuntu' ]; then
    $INSTALL apt-transport-https apt-utils curl gnupg
    mkdir -p /etc/apt/keyrings
    curl -fsSL "https://htcss-downloads.chtc.wisc.edu/repo/keys/HTCondor-${REPO_VERSION}-Key" -o /etc/apt/keyrings/htcondor.asc
    curl -fsSL "https://htcss-downloads.chtc.wisc.edu/repo/$ID/htcondor-${REPO_VERSION}-${VERSION_CODENAME}.list" -o /etc/apt/sources.list.d/htcondor.list
    # Include alpha repositories
    sed -i "/-alpha/s/^#//" /etc/apt/sources.list.d/htcondor.list
    apt-get update
fi

# Use the testing repositories for unreleased software
# Debian/Ubuntu, select on codename
if [ "$VERSION_CODENAME" = 'future' ] && [ "$ARCH" = 'x86_64' ]; then
    cp -p /etc/apt/sources.list.d/htcondor.list /etc/apt/sources.list.d/htcondor-test.list
    sed -i s+repo/+repo-test/+ /etc/apt/sources.list.d/htcondor-test.list
    apt-get update
fi
# Enterprise Linux, select on version
if [ "$ID" = 'future' ] && [ "$VERSION_ID" -eq 10 ] && [ "$ARCH" = 'x86_64_v2' ]; then
    cp -p /etc/yum.repos.d/htcondor.repo /etc/yum.repos.d/htcondor-test.repo
    sed -i s+repo/+repo-test/+ /etc/yum.repos.d/htcondor-test.repo
    sed -i s/\\[htcondor/[htcondor-test/ /etc/yum.repos.d/htcondor-test.repo
    # ] ] Help out vim syntax highlighting
fi
# SUSE is special
if [ "$ID" = 'future-suse' ]; then
    cp -p /etc/zypp/repos.d/htcondor.repo /etc/zypp/repos.d/htcondor-test.repo
    sed -i s+repo/+repo-test/+ /etc/zypp/repos.d/htcondor-test.repo
    sed -i s/\\[htcondor/[htcondor-test/ /etc/zypp/repos.d/htcondor-test.repo
    # ] ] Help out vim syntax highlighting
fi

# Install the build dependencies
if [ "$ID" = 'almalinux' ] || [ "$ID" = 'amzn' ] || [ "$ID" = 'centos' ] || [ "$ID" = 'fedora' ]; then
    $INSTALL make rpm-build yum-utils
    yum-builddep -y /tmp/rpm/condor.spec
fi

# Install the build dependencies
if [ "$ID" = 'opensuse-leap' ] || [ "$ID" = 'sles' ]; then
    $INSTALL make rpm-build
    # shellcheck disable=SC2046 # we want word splitting
    $INSTALL $(rpmspec --parse /tmp/rpm/condor.spec | grep '^BuildRequires:' | sed -e 's/^BuildRequires://' | sed -e 's/,/ /')
fi

# Need newer cmake on bionic
if [ "$VERSION_CODENAME" = 'bionic' ]; then
    curl -dsSL https://apt.kitware.com/keys/kitware-archive-latest.asc | apt-key add -
    echo 'deb https://apt.kitware.com/ubuntu/ bionic main' > /etc/apt/sources.list.d/cmake.list
    apt-get update
fi

if [ "$ID" = 'debian' ] || [ "$ID" = 'ubuntu' ]; then
    $INSTALL build-essential devscripts equivs gpp
    (cd /tmp/debian; ./prepare-build-files.sh -DUW_BUILD)
    mk-build-deps --install --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' /tmp/debian/control
fi

if [ "$VERSION_CODENAME" = 'focal' ]; then
    # Need to upgrade compiler on this old platform
    $INSTALL gcc-10 g++-10
    update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 1000 --slave /usr/bin/g++ g++ /usr/bin/g++-10
fi

if [ "$VERSION_CODENAME" = 'noble' ]; then
    # Upgrade to more recent compiler
    $INSTALL gcc-14 g++-14
    update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 1000 --slave /usr/bin/g++ g++ /usr/bin/g++-14
fi

# Add useful tools
$INSTALL gdb git less python3-pip strace sudo vim
if [ "$ID" = 'almalinux' ] || [ "$ID" = 'amzn' ] || [ "$ID" = 'centos' ] || [ "$ID" = 'fedora' ] || [ "$ID" = 'opensuse-leap' ] || [ "$ID" = 'sles' ]; then
    $INSTALL iputils
    # rpmlint not installable on early versions of AlmaLinux 10.2
    $INSTALL rpmlint || true
fi
if [ "$ID" = 'debian' ] || [ "$ID" = 'ubuntu' ]; then
    $INSTALL lintian net-tools
fi
if [ "$ID" != 'sles' ]; then
    $INSTALL nano
fi

# Use fancy new lief-patchelf
if [ "$ARCH" = 'x86_64' ] || [ "$ARCH" = 'x86_64_v2' ] || [ "$ARCH" = 'aarch64' ]; then
    $INSTALL lief-patchelf
else
    $INSTALL patchelf
fi

# Add in the ninja build system
if [ "$ID" = 'opensuse-leap' ] || [ "$ID" = 'sles' ]; then
    $INSTALL ninja
else
    $INSTALL ninja-build
fi

exists() {
    [ -e "$1" ]
}

# Make the gcc-toolset compiler the default on AlmaLinux
if [ "$ID" = 'almalinux' ]; then
    if exists /opt/rh/gcc-toolset-*/enable; then
        echo . /opt/rh/gcc-toolset-*/enable > /etc/profile.d/gcc.sh
        # shellcheck disable=SC2016 # we want this expanded at runtime
        echo 'export CC=$(which cc)' >> /etc/profile.d/gcc.sh
        # shellcheck disable=SC2016 # we want this expanded at runtime
        echo 'export CXX=$(which c++)' >> /etc/profile.d/gcc.sh
    fi
fi

# Container users can sudo
echo "%$SUDO_GROUP ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/$SUDO_GROUP

# Install HTCondor to build and test BaTLab style
if [ "$ID" = 'debian' ] || [ "$ID" = 'ubuntu' ]; then
    $INSTALL condor libnss-myhostname openssh-server
    # Ensure that gethostbyaddr() returns our hostname
    sed -i -e 's/^hosts:.*/& myhostname/' /etc/nsswitch.conf
fi

if [ "$ID" = 'almalinux' ] || [ "$ID" = 'amzn' ] || [ "$ID" = 'centos' ] || [ "$ID" = 'fedora' ] || [ "$ID" = 'opensuse-leap' ] || [ "$ID" = 'sles' ]; then
    $INSTALL condor hostname java openssh-clients openssh-server openssl
    if [ "$ID" = 'opensuse-leap' ] || [ "$ID" = 'sles' ]; then
        $INSTALL procps
    else
        $INSTALL procps-ng
    fi
    if [ "$ID" != 'amzn' ] && [ "$ID" != 'sles' ]; then
        $INSTALL apptainer fuse-overlayfs
    fi
    $INSTALL 'perl(Archive::Tar)' 'perl(Data::Dumper)' 'perl(Digest::MD5)' 'perl(Digest::SHA)' 'perl(English)' 'perl(Env)' 'perl(File::Copy)' 'perl(FindBin)' 'perl(Net::Domain)' 'perl(Sys::Hostname)' 'perl(Time::HiRes)' 'perl(XML::Parser)'
fi

# Match the current version. Consult:
# https://apptainer.org/docs/admin/latest/installation.html#install-debian-packages
if [ "$ID" = 'debian' ]; then
    if [ "$VERSION_CODENAME" = 'trixie' ]; then
        TRIXIE='-trixie+'
    else
        TRIXIE=''
    fi
    $INSTALL wget
    APPTAINER_VERSION=1.5.1
    wget https://github.com/apptainer/apptainer/releases/download/v${APPTAINER_VERSION}/apptainer_${APPTAINER_VERSION}${TRIXIE}_amd64.deb
    $INSTALL ./apptainer_${APPTAINER_VERSION}${TRIXIE}_amd64.deb
    rm ./apptainer_${APPTAINER_VERSION}${TRIXIE}_amd64.deb
    $INSTALL fuse-overlayfs
fi

if [ "$ID" = 'ubuntu' ]; then
    # Add PPA for older Ubuntu versions
    if [ "$VERSION_CODENAME" = 'jammy' ] || [ "$VERSION_CODENAME" = 'noble' ]; then
        $INSTALL software-properties-common
        add-apt-repository -y ppa:apptainer/ppa
        apt-get update
    fi
    $INSTALL apptainer fuse-overlayfs
fi


# Include packages for tarball in the image.
externals_dir="/usr/local/condor/externals"
mkdir -p "$externals_dir"
if [ "$ID" = 'debian' ] || [ "$ID" = 'ubuntu' ]; then
    chown _apt "$externals_dir"
    pushd "$externals_dir"
    apt-get download libgomp1 libmunge2 libpcre2-8-0 libsqlite3-0 pelican pelican-osdf-compat
    if [ "$VERSION_CODENAME" = 'bullseye' ]; then
        apt-get download libscitokens0 libvomsapi1v5
    elif [ "$VERSION_CODENAME" = 'bookworm' ]; then
        apt-get download libscitokens0 libvomsapi1v5
    elif [ "$VERSION_CODENAME" = 'trixie' ]; then
        apt-get download libscitokens0t64 libvomsapi1t64
    elif [ "$VERSION_CODENAME" = 'focal' ]; then
        apt-get download libscitokens0 libvomsapi1v5
    elif [ "$VERSION_CODENAME" = 'jammy' ]; then
        apt-get download libscitokens0 libvomsapi1v5
    elif [ "$VERSION_CODENAME" = 'noble' ]; then
        apt-get download libscitokens0t64 libvomsapi1t64
    elif [ "$VERSION_CODENAME" = 'resolute' ]; then
        apt-get download libscitokens0t64 libvomsapi1t64
    else
        echo "Unknown codename: $VERSION_CODENAME"
        exit 1
    fi
    popd
fi
if [ "$ID" = 'almalinux' ] || [ "$ID" = 'amzn' ] || [ "$ID" = 'centos' ] || [ "$ID" = 'fedora' ]; then
    yumdownloader --downloadonly --destdir="$externals_dir" \
        libgomp munge-libs pelican pelican-osdf-compat pcre2 sqlite-libs scitokens-cpp
    if [ "$ID" != 'amzn' ]; then
        yumdownloader --downloadonly --destdir="$externals_dir" voms
    fi
    # Remove 32-bit x86 packages if any
    rm -f "$externals_dir"/*.i686.rpm
fi
if [ "$ID" = 'opensuse-leap' ] || [ "$ID" = 'sles' ]; then
    zypper --non-interactive --pkg-cache-dir "$externals_dir" download libgomp1 libpcre2-8-0 pelican pelican-osdf-compat
fi
if [ "$ID" = 'opensuse-leap' ]; then
    zypper --non-interactive --pkg-cache-dir "$externals_dir" download libmunge2 libSciTokens0
fi

# pelican-osdf-compat went to noarch. Unfortunately, the old arch specific RPM is also downloaded
rm -f "$externals_dir"/pelican-osdf-compat-*64.rpm

# Clean up package caches
if [ "$ID" = 'centos' ]; then
    yum clean all
    rm -rf /var/cache/yum/*
fi
if [ "$ID" = 'amzn' ] || [ "$ID" = 'almalinux' ] || [ "$ID" = 'fedora' ]; then
    dnf clean all
    rm -rf /var/cache/yum/*
fi
if [ "$ID" = 'debian' ] || [ "$ID" = 'ubuntu' ]; then
    apt-get -y autoremove
    apt-get -y clean
fi

# Install apptainer into externals directory
if [ "$ID" != 'amzn' ]; then
    if [ "$ID" != 'ubuntu' ] || [ "$ARCH" != 'ppc64le' ]; then
        mkdir -p "$externals_dir/apptainer"
        if [ "$ID" = 'debian' ] || [ "$ID" = 'ubuntu' ]; then
            $INSTALL cpio rpm2cpio
        fi
        curl -s https://raw.githubusercontent.com/apptainer/apptainer/main/tools/install-unprivileged.sh | \
            bash -s - "$externals_dir/apptainer"
        rm -r "$externals_dir/apptainer/$(arch)/libexec/apptainer/cni"
        # Move apptainer out of the default path
        mv "$externals_dir/apptainer/bin" "$externals_dir/apptainer/libexec"
    fi
fi

# Install pytest for BaTLab testing (versions pinned in test-requirements.txt)
# Install sphinx-mermaid so docs can have images
# Install scitokens for BaTLab testing
TEST_REQS=/tmp/test-requirements.txt
if [ "$ID" = 'debian' ] || [ "$ID" = 'ubuntu' ]; then
    if [ "$VERSION_CODENAME" = 'bullseye' ] || [ "$VERSION_CODENAME" = 'focal' ] || [ "$VERSION_CODENAME" = 'jammy' ]; then
        pip3 install -r "$TEST_REQS" scitokens sphinxcontrib-mermaid
    else
        pip3 install --break-system-packages -r "$TEST_REQS" scitokens sphinxcontrib-mermaid
    fi
else
    if [ "$ID" = 'centos' ]; then
        pip3 install -r "$TEST_REQS" sphinxcontrib-mermaid
    else
        pip3 install -r "$TEST_REQS" scitokens sphinxcontrib-mermaid
    fi
fi

if [ "$ID" = 'amzn' ] || [ "$VERSION_CODENAME" = 'bullseye' ] || [ "$VERSION_CODENAME" = 'focal' ]; then
    # Pip installs a updated version of markupsafe that is incompatiable
    # with sphinx on these platforms. Downgrade markupsafe and hope for the best
    pip3 install markupsafe==2.0.1
fi

rm -rf /tmp/*
exit 0
