#!/bin/bash -e
[[ $1 = "-h" ]] || [[ $1 = "--help" ]] && echo "Setup a working openQA installation, automating the steps mentioned in the 'custom installation' documentation section. Supports to immediately clone an existing job simply by supplying 'openqa-clone-job' parameters directly for a quickstart" && exit

set -xeuo pipefail

dbname="${dbname:="openqa"}"
dbuser="${dbuser:="geekotest"}"
running_systemd=
skip_suse_specifics="${skip_suse_specifics:=""}"
skip_suse_tests="${skip_suse_tests:=""}"
setup_web_proxy="${setup_web_proxy:=""}"

if [[ $(ps --no-headers -o comm 1) = 'systemd' ]]; then
    running_systemd=1
fi

start-database() {
    if [[ -z $running_systemd ]]; then
        su postgres -c '/usr/share/postgresql/postgresql-script stop' || true
        su postgres -c '/usr/share/postgresql/postgresql-script start'
    else
        systemctl enable --now postgresql
    fi
}

start-worker() {
    if [[ -z $running_systemd ]]; then
        /usr/bin/install -d -m 0755 -o _openqa-worker /var/lib/openqa/pool/1
        su _openqa-worker -c '/usr/share/openqa/script/worker --instance 1' &
    else
        systemctl enable --now openqa-worker@1
    fi
}

start-daemons() {
    if [[ -z $running_systemd ]]; then
        pgrep -f openqa-scheduler-daemon > /dev/null || su geekotest -c /usr/share/openqa/script/openqa-scheduler-daemon &
        pgrep -f openqa-websockets-daemon > /dev/null || su geekotest -c /usr/share/openqa/script/openqa-websockets-daemon &
        pgrep -f openqa-gru > /dev/null || su geekotest -c /usr/share/openqa/script/openqa-gru &
        pgrep -f openqa-livehandler-daemon > /dev/null || su geekotest -c /usr/share/openqa/script/openqa-livehandler-daemon &
        if [[ $setup_web_proxy == "nginx" ]]; then
            nginx
        else
            /usr/sbin/start_apache2 -k start
        fi
        pgrep -f openqa-webui-daemon > /dev/null || su geekotest -c /usr/share/openqa/script/openqa-webui-daemon &
    else
        if [[ $setup_web_proxy == "nginx" ]]; then
            systemctl enable --now nginx
        else
            systemctl enable --now apache2
        fi
        systemctl enable --now openqa-webui
        systemctl enable --now openqa-scheduler
    fi
}

if [[ $# -gt 0 && $1 == start ]]; then
    start-database
    start-daemons
    start-worker
    exit
fi

# add extra repos for leap
# shellcheck disable=SC1091
. /etc/os-release
if [[ $NAME = "openSUSE Leap" ]]; then
    # avoid using `obs://…` URL to workaround https://bugzilla.opensuse.org/show_bug.cgi?id=1187425
    repobase=https://download.opensuse.org/repositories/devel:/openQA
    # remove suffixes like " Beta" so e.g. "15.6 Beta" becomes just "15.6"
    # shellcheck disable=SC2153
    version=${VERSION%% *}
    zypper lr -d | grep "$repobase/$version" || zypper -n addrepo -p 95 "$repobase/$version" 'devel:openQA'
    zypper lr -d | grep "$repobase:/Leap:/$version/$version" || zypper -n addrepo -p 90 "$repobase:/Leap:/$version/$version" "devel:openQA:Leap:$version"
    zypper -n --gpg-auto-import-keys refresh
fi

# Ensure we have retry available to handle temporary package issues later
command -v retry > /dev/null || zypper -n --gpg-auto-import-keys in retry

# install packages
pkgs=(qemu-arm qemu-ppc qemu-x86 qemu-tools sudo iputils os-autoinst-distri-opensuse-deps)

if [[ "$(uname -m)" = "aarch64" ]]; then
    pkgs+=(qemu-uefi-aarch64)
fi
if [[ $setup_web_proxy == "nginx" ]]; then
    pkgs+=(openQA-single-instance-nginx)
else
    pkgs+=(openQA-single-instance)
fi

# this was split into a separate package on newer dist versions - so install it if available
if zypper -n search -x qemu-hw-display-virtio-gpu-pci; then
    pkgs+=(qemu-hw-display-virtio-gpu qemu-hw-display-virtio-gpu-pci)
fi
packages="${pkgs[*]}"
retry -e -s 30 -r 7 -- sh -c "zypper -n --gpg-auto-import-keys ref && zypper -n in --no-recommends $packages"

# setup database
chown -R postgres: /var/lib/pgsql/ # fix broken postgres working dir permissions in the nspawn container
start-database
su postgres -c "/usr/share/openqa/script/setup-db" "$dbuser" "$dbname"

# setup webserver and fake-auth
proxy_args=""
[[ -n "$setup_web_proxy" ]] && proxy_args="--proxy=$setup_web_proxy"
setup=/usr/share/openqa/script/configure-web-proxy
if command -v $setup; then
    bash -ex $setup "$proxy_args"
else
    curl -s https://raw.githubusercontent.com/os-autoinst/openQA/master/script/configure-web-proxy | bash -ex -s -- "$proxy_args"
fi
sed -i -e 's/#*.*method.*=.*$/method = Fake/' /etc/openqa/openqa.ini

if [[ -z $skip_suse_specifics ]] && ping -c1 download.suse.de. && (! rpm -q ca-certificates-suse); then
    # add internal CA if executed within suse network
    if ! zypper info ca-certificates-suse | grep -q ':'; then
        # add suse ca repo if needed
        # use this way of adding the repo to be distro agnostic
        if [ "$NAME" = "openSUSE Leap" ]; then
            # avoid using `obs://…` URL to workaround https://bugzilla.opensuse.org/show_bug.cgi?id=1187425
            zypper -n addrepo "http://download.suse.de/ibs/SUSE:/CA/${VERSION}" 'SUSE:CA'
        elif [ "$NAME" = "SLES" ]; then
            zypper -n addrepo "http://download.suse.de/ibs/SUSE:/CA/SLE_${VERSION/-/_}" 'SUSE:CA'
        else
            zypper -n addrepo obs://SUSE:CA SUSE:CA
        fi
        sed -i -e 's#download.opensuse.org/repositories#download.suse.de/ibs#' /etc/zypp/repos.d/SUSE:CA.repo
        sed -i -e 's/https/http/' /etc/zypp/repos.d/SUSE:CA.repo
        zypper -n --gpg-auto-import-keys refresh
    fi
    zypper -n install --no-recommends -ly ca-certificates-suse
fi

# fetch tests and needles
if [[ -z $skip_suse_tests ]]; then
    if ping -c1 gitlab.suse.de.; then
        # use faster local mirror if run from within SUSE network
        export needles_giturl="https://gitlab.suse.de/openqa/os-autoinst-needles-opensuse-mirror.git"
    fi
    /usr/share/openqa/script/fetchneedles
    if [[ ! -e /var/lib/openqa/tests/sle ]]; then
        ln -s opensuse /var/lib/openqa/tests/sle
    fi

    if ping -c1 gitlab.suse.de.; then
        sles_needles_giturl="https://gitlab.suse.de/openqa/os-autoinst-needles-sles.git"
        sles_needles_directory="/var/lib/openqa/tests/opensuse/products/sle/needles"
        # clone SLE needles if run from within SUSE network
        if [[ ! -d $sles_needles_directory ]]; then
            echo "cloning $sles_needles_giturl shallow. Call 'git fetch --unshallow' for full history"
            git clone --depth 1 "$sles_needles_giturl" "$sles_needles_directory"
        fi
        chown -R "$dbuser:" /var/lib/openqa/tests/opensuse/products/sle/needles
    fi
fi

# ensure that the hostname is mapped to 127.0.0.1 (needed for livehandler)
grep -q "$(hostname)" /etc/hosts || echo "127.0.0.1 $(hostname)" >> /etc/hosts

start-daemons

# wait for webui to become available
while ! curl -sI http://localhost/ | grep 200; do
    sleep 3
done

# create api key
curl http://localhost/login # create demo user (id=2)
API_KEY=$(hexdump -n 8 -e '2/4 "%08X" 1 "\n"' /dev/random)
API_SECRET=$(hexdump -n 8 -e '2/4 "%08X" 1 "\n"' /dev/random)
echo "INSERT INTO api_keys (key, secret, user_id, t_created, t_updated) VALUES ('${API_KEY}', '${API_SECRET}', 2, NOW(), NOW());" | su postgres -c "psql $dbname"

cat >> /etc/openqa/client.conf << EOF
[localhost]
key = ${API_KEY}
secret = ${API_SECRET}
EOF

start-worker

# clone job if job ID is given passing extra arguments as well
# e.g.: openqa-bootstrap --from openqa.opensuse.org 12345 SCHEDULE=tests/boot/boot_to_desktop,tests/x11/kontact
if [[ $# -ne 0 ]]; then
    openqa-clone-job "$@"
fi

# wait forever without systemd (assuming we are running as container entrypoint)
# see https://progress.opensuse.org/issues/164595?#note-5
[[ -n $running_systemd ]] || wait
