#!/usr/bin/bash
# veilor-update — system update wrapper.
# Wraps `dnf upgrade --refresh` + `flatpak update` behind a single command.
# User-facing CLI shipped in /usr/local/bin/. v0.6 ergonomic tooling.
#
# Exit codes:
#   0  success
#   1  dnf failed
#   2  flatpak failed (dnf still ran successfully)
#   3  no network
#
# Uses `gum` for spinner output if present, falls back to plain stdout.

set -uo pipefail

# ── Helpers ─────────────────────────────────────────────────────────
have() { command -v "$1" >/dev/null 2>&1; }

GUM=$(have gum && echo gum || echo "")

say() {
    # Print a status line. Coloured if gum present, else plain.
    if [[ -n $GUM ]]; then
        gum style --foreground 212 --bold "$1"
    else
        printf '\n=== %s ===\n' "$1"
    fi
}

run_with_spinner() {
    local title=$1; shift
    if [[ -n $GUM ]]; then
        gum spin --spinner dot --title "$title" -- "$@"
    else
        echo "[+] $title"
        "$@"
    fi
}

# ── Pre-flight: network check ───────────────────────────────────────
say "veilor-update: checking network"
if ! ping -c 1 -W 2 mirrors.fedoraproject.org >/dev/null 2>&1; then
    echo
    echo "  No route to mirrors.fedoraproject.org."
    echo "  Connect to a network and re-run \`veilor-update\`."
    exit 3
fi

# ── Snapshot kernel before upgrade so we can warn about reboot need ─
KERNEL_BEFORE=$(uname -r)

# ── DNF upgrade ─────────────────────────────────────────────────────
say "veilor-update: refreshing DNF metadata + applying updates"
# Capture upgrade output so we can count packages afterwards. Tee to
# stdout for live progress; swallow into a tempfile for the count.
LOG=$(mktemp -t veilor-update.XXXXXX)
trap 'rm -f "$LOG"' EXIT

if ! sudo dnf upgrade --refresh -y 2>&1 | tee "$LOG"; then
    echo
    echo "  dnf upgrade failed. See output above."
    exit 1
fi

# ── Count packages updated ──────────────────────────────────────────
# DNF prints "Upgraded: N", "Installed: N", "Removed: N" at end.
# Sum the upgrade/install lines for the user-visible total.
UPDATED=$(grep -E '^(Upgraded|Installed)\b' "$LOG" 2>/dev/null \
    | awk -F: '{ gsub(/[^0-9]/,"",$2); s+=$2 } END { print s+0 }')

# ── Flatpak (best-effort) ───────────────────────────────────────────
FLATPAK_RC=0
if have flatpak; then
    say "veilor-update: updating flatpaks"
    if ! flatpak update -y; then
        FLATPAK_RC=2
        echo "  flatpak update failed; continuing anyway."
    fi
else
    echo "  (flatpak not installed — skipping)"
fi

# ── Post-update: reboot hint if kernel changed ──────────────────────
KERNEL_AFTER_LATEST=$(rpm -q kernel --last 2>/dev/null \
    | awk 'NR==1 { sub(/^kernel-/,"",$1); print $1 }')

say "veilor-update: complete"
printf '  Packages updated : %s\n' "${UPDATED:-0}"
printf '  Running kernel   : %s\n' "$KERNEL_BEFORE"
if [[ -n ${KERNEL_AFTER_LATEST:-} && $KERNEL_AFTER_LATEST != "$KERNEL_BEFORE" ]]; then
    printf '  Newest kernel    : %s (reboot suggested)\n' "$KERNEL_AFTER_LATEST"
fi

exit $FLATPAK_RC
