#!/bin/bash
set -e

LOGFILE="/var/log/xivocc_install_$(date +'%Y%m%d_%H%M%S').log"

mkdir -p "$(dirname "$LOGFILE")"
exec > >(tee -a "$LOGFILE") 2>&1

mirror_xivo="http://mirror.xivo.solutions"
update='apt-get update'
install='apt-get install --assume-yes'
download='apt-get install --assume-yes --download-only'
dcomp='/usr/bin/xivocc-dcomp'

distribution='xivo-pollux'
dev_lts='quantum'
repo='debian'
debian_codename='trixie'
debian_version='13'
debian_codename_dev='trixie'
debian_version_dev='13'
not_installable_message='This version of XiVO CC is not installable on 32-bit systems.'

declare -A lts_version_table=([2017.03]="Five" [2017.11]="Polaris" [2018.05]="Aldebaran" [2018.16]="Borealis" [2019.05]="Callisto" [2019.12]="Deneb" [2020.07]="Electra" [2020.18]="Freya" [2021.07]="Gaia" [2021.15]="Helios" [2022.05]="Izar" [2022.10]="Jabbah" [2023.05]="Kuma" [2023.10]="Luna" [2024.05]="Maia" [2024.10]="Naos" [2025.05]="Orion" [2025.10]="Pollux")

# 6099 Force the usage of ipV4 on the wget commands to avoid infinite loop
if ! grep --quiet "inet4_only = on" /etc/wgetrc; then
    echo "inet4_only = on" >>/etc/wgetrc
fi

get_system_architecture() {
    architecture=$(uname -m)
}

check_system() {
    local version_file='/etc/debian_version'
    if [ ! -f $version_file ]; then
        echo "You must install XiVO CC on a Debian $debian_version (\"$debian_codename\") system"
        echo "You do not seem to be on a Debian system"
        exit 1
    else
        your_version=$(cut -d '.' -f 1 "$version_file")
    fi

    if [ "$your_version" != $debian_version ]; then
        echo "You must install XiVO CC on a Debian $debian_version (\"$debian_codename\") system"
        echo "You are currently on a Debian $your_version system"
        exit 1
    fi
}

add_dependencies() {
    $update
    # dirmngr and gnupg is needed by apt-key in Debian 9-10
    $install wget \
        dirmngr \
        gnupg \
        ca-certificates \
        curl
}

add_xivo_key() {
    local xivo_keyring_file="/etc/apt/trusted.gpg.d/mirror.xivo.solutions.gpg"
    add_key_in_keyring "http://mirror.xivo.solutions/xivo_current.key" "${xivo_keyring_file}"
}

add_postgresql_sources_list() {
    local distribution="${1:-bookworm}"; shift

	cat > /etc/apt/sources.list.d/pgdg.list <<-EOF
	deb http://apt.postgresql.org/pub/repos/apt/ ${distribution}-pgdg main
	EOF

    add_key_in_keyring "https://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc" "/etc/apt/trusted.gpg.d/apt.postgresql.org.gpg"
}


is_key_in_keyring() {
    local keyid="${1}"
    shift
    local keyringfile="${1}"
    shift

    if gpg --batch --no-tty --keyring "${keyringfile}" --list-keys --with-colons | grep -q "${keyid}"; then
        return 0
    else
        return 1
    fi
}

add_key_in_keyring() {
    local keyurl="${1}"
    shift
    local keyringfile="${1}"
    shift

    echo "Removing file ${keyringfile}"
    rm -rf "${keyringfile}"
    touch "${keyringfile}"
    echo "Adding GPG key from ${keyurl} to ${keyringfile}..."
    curl -fsSL "${keyurl}" | gpg --dearmor | tee "${keyringfile}" >/dev/null
}

# For archive versions. From version 2019.11 docker key is installed by xivo-docker
add_docker_key() {
    local docker_keyring_file="/etc/apt/trusted.gpg.d/download.docker.com.gpg"
    local docker_keyid="0EBFCD88"

    if ! is_key_in_keyring "${docker_keyid}" "${docker_keyring_file}"; then
        echo "Adding Docker GPG key..."
        add_key_in_keyring "https://download.docker.com/linux/debian/gpg" "${docker_keyring_file}"
    fi
}

add_mirror() {
    echo "Add mirrors informations"
    local mirror="deb $mirror_xivo/$repo $distribution main"
    apt_dir="/etc/apt"
    sources_list_dir="$apt_dir/sources.list.d"
    if ! grep -qr "$mirror" "$apt_dir"; then
        echo "$mirror" >$sources_list_dir/tmp-pf.sources.list
    fi
    add_xivo_key
    add_postgresql_sources_list $debian_codename

    export DEBIAN_FRONTEND=noninteractive
    $update
    $install xivo-dist
    xivo-dist "$distribution"

    rm -f "$sources_list_dir/tmp-pf.sources.list"
    $update
}

install_xivocc() {
    # Install docker stuff
    ${install} docker-ce

    ${download} xivocc-installer
    ${install} xivocc-installer

    if [ $dev_install = true ]; then
        mkdir -p /etc/docker/compose
        echo "XIVOCC_DIST=latestdev" >> /etc/docker/compose/custom.env
    fi

    if [ $rc_install = true ]; then
        mkdir -p /etc/docker/compose
        echo "XIVOCC_DIST=latestrc" >> /etc/docker/compose/custom.env
    fi

    if [ -f "${dcomp}" ]; then
        ${dcomp} pull
    fi

}

check_system_is_64bit() {
    if [ "$architecture" != "x86_64" ]; then
        echo "$not_installable_message"
        exit 1
    fi
}

check_archive_prefix() {
    if [ "${1::5}" = "xivo-" ]; then
        echo 'Archive version must be typed without the prefix "xivo-"'
        exit 1
    fi
}

usage() {
    cat <<EOF
    This script is used to install XiVO CC

    usage : $(basename $0) [-s] [-d|-a version|-r version]
        whitout arg : install production version
        -d          : install development version
        -a version  : install archived version (2018.16 or later)
        -r version  : install rc version
        -s          : run the installer in silent mode

EOF
    exit 1
}

get_version_name() {
    if [[ -v lts_version_table[$1] ]]; then
        echo "${lts_version_table[$1]}"
    else
        echo 'intermediate version'
    fi
}

ask_before_proceeding_installation_cc() {
    user_has_been_asked_before=1
    local option=$1
    local version=$2
    local version_prefix=${2:0:7}
    if [[ $# -eq 0 ]]; then
        echo "You are going to install production version : $distribution."
    elif [[ $version_prefix =~ ^[0-9]{4}\.[0-9]{2}+$ ]] && [[ $option == "-a" ]]; then
        echo "You are going to install xivocc $(get_version_name $version_prefix) ($version)."
    elif [[ $option == "-d" ]]; then
        echo "You are going to install XiVO CC ${dev_lts} dev version."
        echo "To install production version, re-run the script without parameters."
    else
        echo "Be careful ! The version $option $version you choose was not recognized."
    fi

    echo "The installation will start in 5 seconds. Type Ctrl+C if you want to abort."
    for _ in $(seq 1 1 5); do
        sleep 1
        echo -n "."
    done
    echo "Go!"
    sleep 1
}

recover_from_wrong_distrib_input() {
    if [ -f /etc/apt/sources.list.d/tmp-pf.sources.list ]; then
        rm /etc/apt/sources.list.d/tmp-pf.sources.list
    fi
}

do_archive_install() {
    local version="$1"
    check_archive_prefix $version
    ask_before_proceeding_installation_cc -a $version
    distribution="xivo-$version"
    repo='archive'

    if dpkg --compare-versions "$version" "ge" "2026.01"; then
        debian_version=$debian_version
        debian_codename=$debian_codename
    elif dpkg --compare-versions "$version" "ge" "2024.05"; then
        debian_version='12'
        debian_codename='bookworm'
    elif dpkg --compare-versions "$version" "ge" "2022.03"; then
        debian_version='11'
        debian_codename='bullseye'
    elif dpkg --compare-versions "$version" "ge" "2020.12"; then
        debian_version='10'
        debian_codename='buster'
    elif dpkg --compare-versions "$version" "ge" "2018.16"; then
        debian_version='9'
        debian_codename='stretch'
        add_docker_key
    fi

    if dpkg --compare-versions "$version" "le" "2018.15.00"; then
        # 2018.16 and earlier don't have mds available
        echo "This script only supports installing XiVO 2018.16 or later."
        exit 1
    fi
}

get_system_architecture
check_system_is_64bit

user_has_been_asked_before=0
while getopts ':sdr:a:' opt; do
    case ${opt} in
    s)
        echo -e "\e[1;32mStarting Silent mode\e[0m"
        export DEBIAN_FRONTEND=noninteractive
        ;;
    d)
        ask_before_proceeding_installation_cc -d
        distribution="xivo-$dev_lts-dev"
        debian_codename=$debian_codename_dev
        debian_version=$debian_version_dev
        dev_install=true
        ;;
    r)
        rc_install=true
        do_archive_install "$OPTARG"
        ;;
    a)
        do_archive_install "$OPTARG"
        ;;
    *)
        usage
        ;;
    esac
done
if [[ ${user_has_been_asked_before} -eq 0 ]]; then
    ask_before_proceeding_installation_cc $1 $2
fi
recover_from_wrong_distrib_input

check_system
add_dependencies
add_mirror
install_xivocc
