#!/bin/bash
### BEGIN INIT INFO
# Provides:          elive-distro-upgrader
# Required-Start:    $remote_fs $syslog $network
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# X-Start-Before:    $x-display-manager lightdm gdm gdm3 sddm xdm slim nodm display-manager
# Short-Description: Perform Debian distribution upgrade on boot
# Description:       This script performs a one-time Debian distribution
#                    upgrade on boot, configured via /etc/default/elive-distro-upgrade.
### END INIT INFO

# Use LSB init functions
. /lib/lsb/init-functions

DEFAULTS_FILE="/etc/default/elive-distro-upgrade"
BOOT_UPGRADER="/usr/lib/elive-upgrader/elive-boot-upgrader"
LOCK_FILE="/tmp/.debian-upgrader.lock"

# Disable OpenRC start/stop timeouts for long-running upgrades
rc_timeout=0
export RC_TIMEOUT=0

# Read configuration
if [ -r "$DEFAULTS_FILE" ]; then
    . "$DEFAULTS_FILE"
fi

depend() {
    need localmount
    after bootmisc
    before xdm lightdm gdm gdm3 sddm slim nodm display-manager
}

UPGRADE_ENABLED="${UPGRADE_ENABLED:-no}"
UPGRADE_IN_PROGRESS="${UPGRADE_IN_PROGRESS:-no}"
TARGET_CODENAME="${TARGET_CODENAME:-}"
REBOOT_COUNT="${REBOOT_COUNT:-0}"
CURRENT_STEP="${CURRENT_STEP:-}"

case "$1" in
    depend)
        depend
        ;;

    start)
        if [ "$UPGRADE_ENABLED" != "yes" ] || [ ! -f "$DEFAULTS_FILE" ]; then
            exit 0
        fi

        log_daemon_msg "Starting Debian distribution upgrade" "elive-distro-upgrader"

        if [ ! -x "$BOOT_UPGRADER" ]; then
            log_failure_msg "$BOOT_UPGRADER not found or not executable"
            exit 1
        fi

        # Run the boot upgrader script in background so OpenRC/SysVinit returns immediately without timing out
        ("$BOOT_UPGRADER" >/dev/console 2>&1 &)
        log_end_msg 0
        exit 0
        ;;

    stop)
        log_action_msg "Stopping elive-distro-upgrader..."
        if [ -f "$LOCK_FILE" ]; then
            lock_pid="$(cat "$LOCK_FILE" 2>/dev/null)"
            if [ -n "$lock_pid" ] && kill -0 "$lock_pid" 2>/dev/null; then
                log_action_msg "Sending SIGTERM to upgrade process (PID: $lock_pid)..."
                kill -TERM "$lock_pid" 2>/dev/null || true
                sleep 2
                if kill -0 "$lock_pid" 2>/dev/null; then
                    log_action_msg "Force killing upgrade process (PID: $lock_pid)..."
                    kill -9 "$lock_pid" 2>/dev/null || true
                fi
            fi
            rm -f "$LOCK_FILE"
        fi
        if [ -f /etc/inittab.bak-upgrader ]; then
            mv -f /etc/inittab.bak-upgrader /etc/inittab 2>/dev/null || true
        fi
        if [ -f /etc/inittab ]; then
            sed -i 's/^#DISABLED-BY-UPGRADER#//' /etc/inittab 2>/dev/null || true
            telinit q 2>/dev/null || kill -HUP 1 2>/dev/null || true
        fi
        rm -f /etc/inittab.bak-upgrader 2>/dev/null || true
        log_action_msg "Upgrade process stopped. Run 'start' to resume or use debian-upgrader --cancel to abort."
        ;;

    restart|force-reload)
        log_action_msg "Restarting elive-distro-upgrader..."
        "$0" stop
        sleep 1
        "$0" start
        ;;

    status)
        log_action_msg "Debian upgrade status:"
        log_action_msg "  Enabled: $UPGRADE_ENABLED"
        log_action_msg "  In Progress: $UPGRADE_IN_PROGRESS"
        log_action_msg "  Target: $TARGET_CODENAME"
        log_action_msg "  Reboot Count: $REBOOT_COUNT"
        log_action_msg "  Current Step: ${CURRENT_STEP:-none}"

        # Get current codename
        source /usr/lib/elive-upgrader/functions.sh 2>/dev/null || true
        current_release_full="$(cat /etc/debian_version 2>/dev/null || echo "unknown")"
        current_version_number="$(echo "$current_release_full" | cut -d'.' -f1)"
        current_cn=""
        if command -v debian_version_to_codename &>/dev/null; then
            current_cn="$(debian_version_to_codename "$current_version_number")"
        fi
        if [ -z "$current_cn" ] || [ "$current_cn" = "unknown" ]; then
            case "$current_release_full" in
                15*|*duke*)     current_cn="duke" ;;
                14*|*forky*)    current_cn="forky" ;;
                13*|*trixie*)   current_cn="trixie" ;;
                12*|*bookworm*) current_cn="bookworm" ;;
                11*|*bullseye*) current_cn="bullseye" ;;
                10*|*buster*)   current_cn="buster" ;;
                *)              current_cn="unknown" ;;
            esac
        fi

        log_action_msg "  Current Version: $current_cn"
        if [ -f "$LOCK_FILE" ]; then
            lock_pid="$(cat "$LOCK_FILE" 2>/dev/null)"
            if [ -n "$lock_pid" ] && kill -0 "$lock_pid" 2>/dev/null; then
                log_action_msg "  Running: yes (PID: $lock_pid)"
            else
                log_action_msg "  Running: no (stale lock file)"
            fi
        else
            log_action_msg "  Running: no"
        fi
        if [ "$UPGRADE_ENABLED" = "yes" ] && [ "$UPGRADE_IN_PROGRESS" = "yes" ] && [ -n "$TARGET_CODENAME" ]; then
            log_action_msg "Upgrade is configured to run on next boot."
            exit 0
        else
            log_action_msg "Upgrade is not configured to run on next boot."
            exit 3
        fi
        ;;

    *)
        echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2
        exit 3
        ;;
esac

exit 0
