#!/bin/bash

# shellcheck source=../xivo-upgrade-functions
source /usr/bin/xivo-upgrade-functions

get_mds_version_installed_from_apt() {
    echo "$(LANG='C' apt-cache policy xivo-mds-installer | grep Installed | grep -oE '[0-9]{2,4}\.[0-9]+(\.[0-9]+)?|1\.2\.[0-9]{1,2}' | head -n1)"
}

get_mds_version_candidate_from_apt() {
    echo "$(LANG='C' apt-cache policy xivo-mds-installer | grep Candidate | grep -oE '[0-9]{2,4}\.[0-9]+(\.[0-9]+)?|1\.2\.[0-9]{1,2}' | head -n1)"
}

export_mds_version_to_env() {
    export MDS_VERSION_INSTALLED=$(get_mds_version_installed_from_apt)
    export MDS_VERSION_CANDIDATE=$(get_mds_version_candidate_from_apt)
}

display_mds_version() {
    local mds_version_candidate_colored
    mds_version_candidate_colored=$(color_diff_between_versions "$MDS_VERSION_INSTALLED" "$MDS_VERSION_CANDIDATE")
    echo ""
    echo "installed version : $MDS_VERSION_INSTALLED"
    echo -e "proposed update   : $mds_version_candidate_colored"
}

stop_mds() {
    xivo-service stop all
}

start_mds() {
    xivo-dcomp up -d --remove-orphans
    xivo-service start
}

install_xivo_docker() {
    apt install --yes xivo-docker
}

exec_bullseye_to_bookworm_migration() {
    local force_yes="--allow-downgrades --allow-remove-essential --allow-change-held-packages"

    add_xivo_apt_conf

    display_upgrade_notice "Executing pre-bookworm upgrade actions..."
    # Force install of new dahdi-linux-dkms module before switching to bookworm
    apt install --yes ${force_yes} -o Dpkg::Options::="--force-confnew" dahdi-linux-dkms

    # On MDS, force install of xivo-config before upgrade
    apt install --yes ${force_yes} -o Dpkg::Options::="--force-confnew" xivo-config

    switch_to_bookworm

    apt update

    display_upgrade_notice "Executing manual upgrade actions..."

    ## Docker specific part
    ## We want to control docker installation in order to not have uncontrolled container restart in the middle of the upgrade

    # Docker installation preparation
    install_xivo_docker

    # Upgrade docker-ce before xivo upgrade
    # shellcheck disable=SC2086
    apt install --yes ${force_yes} -o Dpkg::Options::="--force-confnew" docker-ce docker-ce-cli containerd.io

    # Install xivo-mds-installer to have new xivo-dcomp (which uses docker compose v2)
    # (Do not use --force-confnew to not force-rewrite factory.env file)
    # shellcheck disable=SC2086
    apt-get install --yes ${force_yes} xivo-mds-installer

    # re-stopping services after docker upgrade
    xivo-service stop
    ## End of docker specific part

    apt update

    display_upgrade_notice "Executing MDS full upgrade actions..."
    # shellcheck disable=SC2086
    apt dist-upgrade --yes ${force_yes} -o Dpkg::Options::="--force-confnew"

    apt update
    display_upgrade_notice "Executing cleaning actions..."
    remove_deactivated_sources_list
    apt update
    apt autoremove --yes
}

mds_upgrade() {
    apt update

    pre_stop "mds"
    stop_mds
    post_stop "mds"
    display_upgrade_notice "Upgrading mds..."
    if is_bullseye; then
        export XIVO_SYSTEM_UPGRADE=1
        exec_bullseye_to_bookworm_migration
    else
        display_upgrade_notice "Upgrading media server..."
        display_upgrade_notice "Executing manual upgrade actions..."
        apt install --yes -o Dpkg::Options::="--force-confnew" xivo-config xivo-dist
        display_upgrade_notice "Executing full upgrade actions..."
        apt dist-upgrade --yes -o Dpkg::Options::="--force-confnew"
        display_upgrade_notice "Executing cleaning actions..."
        apt autoremove --yes
    fi

    upgrade_db

    pre_start "mds"
    start_mds
    post_start "mds"
    display_upgrade_notice "Running post-upgrade actions..."
    if [[ "$XIVO_SYSTEM_UPGRADE" == "1" ]]; then
        check_if_grub_is_broken
        display_system_upgrade_reboot_notice
        display_sources_list_notice
    fi
}

upgrade_db() {
    xivo-dcomp upgrade-db
    wait_for_postgres
}

recreate_upgrade_status_file_and_export() {
    local status_file="${1}"; shift

    rm -f "${status_file}"
    touch "${status_file}"
    export MDS_UPGRADE_STATUS_FILE=${status_file}
}


upgrading_system() {
    local force="${1}"; shift

    if is_bullseye; then
        display_system_upgrade_notice
    fi
    display_mds_version
    ask_to_continue_upgrade "${force}"
    local mds_upgrade_status_file="/tmp/mds-upgrade.status"
    recreate_upgrade_status_file_and_export "${mds_upgrade_status_file}"

    mds_upgrade
}

usage() {
    local progname="${1}"; shift

    echo "usage: ${progname} [-d] [-f] [-h]"
    echo -e "\t-d: only download packages"
    echo -e "\t-f: force install the proposed version"
    echo -e "\t-h: print usage"
}

main() {
    local progname="mds-upgrade"
    # Parse flags
    local download_only
    local force
    while getopts :dfh opt
    do
        case ${opt} in
            d) download_only=1;;
            f) force=1;;
            h)
                usage "${progname}"
                exit 0
            ;;
            '?')
                echo "${progname} : option ${OPTARG} is not valid" >&2
                usage "${progname}"
                exit 1
            ;;
        esac
    done
    download_only="${download_only:-"0"}"
    force="${force:-"0"}"

    # Beginning
    export DEBIAN_FRONTEND=noninteractive
    export APT_LISTCHANGES_FRONTEND=none

    export_mds_version_to_env

    if (! is_bullseye && ! is_bookworm); then
        echo "Upgrade aborted."
        echo "Your MDS is lower than Izar (2022.05) and uses Debian 10 (or lower)"
        echo "Upgrade to MDS >= 2024.05 (which uses Debian 12) is not supported"
        echo "You MUST first upgrade to a MDS >= Izar (2022.05)"
        exit 1
    fi

    if [ $download_only -eq 0 ]; then
        upgrading_system "${force}"
    else
        if is_bullseye; then
            # Switch repo to bookworm
            switch_to_bookworm
            apt update

            # Download packages
            apt -y -d -o Dpkg::Options::="--force-confnew" dist-upgrade

            # Rollback
            rollback_apt_sources_list
            apt update
        else
            # Download packages
            apt -y -d -o Dpkg::Options::="--force-confnew" dist-upgrade
        fi
        # Pull container
        export XIVOCC_TAG=$(echo $MDS_VERSION_CANDIDATE | cut -d'.' -f1,2)
        xivo-dcomp pull --ignore-pull-failures
    fi
}

main "${@}"
