#!/usr/bin/env bash
set -Eeuo pipefail

# North Rivet Technical Library
# Radxa Debian 12 Bookworm KDE -> Debian GNOME conversion
#
# Tested workflow target:
#   Radxa ROCK 5B Plus
#   Official Radxa Debian 12 Bookworm image
#
# Normal conversion:
#   chmod +x convert-radxa-bookworm-kde-to-gnome.sh
#   ./convert-radxa-bookworm-kde-to-gnome.sh
#
# After GNOME has been verified after a reboot:
#   ./convert-radxa-bookworm-kde-to-gnome.sh --remove-kde
#
# The cleanup phase deliberately does NOT run apt autoremove. A dry-run
# autoremove report is created for review instead.

MODE="install"

usage() {
    cat <<'USAGE'
North Rivet - Radxa Bookworm KDE to Debian GNOME Converter

Usage:
  ./convert-radxa-bookworm-kde-to-gnome.sh
  ./convert-radxa-bookworm-kde-to-gnome.sh --remove-kde
  ./convert-radxa-bookworm-kde-to-gnome.sh --help

Modes:
  default       Install Debian GNOME and make GDM the default display manager.
                KDE is intentionally left installed until GNOME is verified.

  --remove-kde  Remove the high-level KDE/Plasma desktop packages after GNOME
                has been verified. Does NOT run apt autoremove.
USAGE
}

case "${1:-}" in
    "")
        MODE="install"
        ;;
    --remove-kde|remove-kde)
        MODE="remove-kde"
        ;;
    -h|--help)
        usage
        exit 0
        ;;
    *)
        printf 'ERROR: Unknown option: %s\n\n' "$1" >&2
        usage >&2
        exit 2
        ;;
esac

if [[ ${EUID} -eq 0 ]]; then
    SUDO=()
else
    command -v sudo >/dev/null 2>&1 || {
        echo "ERROR: sudo is required when this script is not run as root." >&2
        exit 1
    }
    SUDO=(sudo)
fi

need_cmd() {
    command -v "$1" >/dev/null 2>&1 || {
        printf 'ERROR: Required command not found: %s\n' "$1" >&2
        exit 1
    }
}

for cmd in apt-get apt-mark dpkg-query systemctl tee date grep readlink; do
    need_cmd "$cmd"
done

[[ -r /etc/os-release ]] || {
    echo "ERROR: /etc/os-release is not readable." >&2
    exit 1
}

# shellcheck disable=SC1091
source /etc/os-release

if [[ "${ID:-}" != "debian" || "${VERSION_CODENAME:-}" != "bookworm" ]]; then
    echo "ERROR: This script is intended for Debian 12 Bookworm." >&2
    printf 'Detected: ID=%s VERSION_CODENAME=%s\n' \
        "${ID:-unknown}" "${VERSION_CODENAME:-unknown}" >&2
    exit 1
fi

MODEL="unknown"
if [[ -r /proc/device-tree/model ]]; then
    MODEL="$(tr -d '\000' < /proc/device-tree/model)"
fi

STAMP="$(date +%Y%m%d-%H%M%S)"
BACKUP_DIR="/var/backups/northrivet-radxa-desktop-${STAMP}"

printf '\n============================================================\n'
printf ' North Rivet - Radxa Debian Desktop Conversion\n'
printf '============================================================\n'
printf 'OS:           %s\n' "${PRETTY_NAME:-Debian 12 Bookworm}"
printf 'Board:        %s\n' "${MODEL}"
printf 'Architecture: %s\n' "$(dpkg --print-architecture)"
printf 'Kernel:       %s\n' "$(uname -r)"
printf 'Mode:         %s\n\n' "${MODE}"

backup_state() {
    echo "Creating pre-change record: ${BACKUP_DIR}"
    "${SUDO[@]}" install -d -m 0755 "${BACKUP_DIR}"

    dpkg-query -W -f='${binary:Package}\t${Version}\t${db:Status-Abbrev}\n' \
        | "${SUDO[@]}" tee "${BACKUP_DIR}/packages-before.txt" >/dev/null

    if [[ -f /etc/apt/sources.list ]]; then
        "${SUDO[@]}" cp -a /etc/apt/sources.list "${BACKUP_DIR}/"
    fi

    if [[ -d /etc/apt/sources.list.d ]]; then
        "${SUDO[@]}" cp -a /etc/apt/sources.list.d "${BACKUP_DIR}/"
    fi

    if [[ -f /etc/X11/default-display-manager ]]; then
        "${SUDO[@]}" cp -a /etc/X11/default-display-manager "${BACKUP_DIR}/"
    fi
}

install_gnome() {
    backup_state

    echo
    echo "Updating Debian package metadata..."
    "${SUDO[@]}" apt-get update

    # Avoid the interactive display-manager selection dialog. GDM is the
    # intended display manager for the Debian GNOME desktop.
    if command -v debconf-set-selections >/dev/null 2>&1; then
        printf '%s\n' \
            'gdm3 shared/default-x-display-manager select gdm3' \
            'sddm shared/default-x-display-manager select gdm3' \
            | "${SUDO[@]}" debconf-set-selections
    fi

    echo
    echo "Installing Debian's standard GNOME desktop task and GDM..."
    "${SUDO[@]}" env DEBIAN_FRONTEND=noninteractive \
        apt-get install -y task-gnome-desktop gdm3

    echo
    echo "Making GDM the default graphical login manager..."

    if systemctl list-unit-files sddm.service >/dev/null 2>&1; then
        "${SUDO[@]}" systemctl disable sddm.service >/dev/null 2>&1 || true
    fi

    "${SUDO[@]}" systemctl enable --force gdm3.service >/dev/null 2>&1 || true
    printf '/usr/sbin/gdm3\n' \
        | "${SUDO[@]}" tee /etc/X11/default-display-manager >/dev/null
    "${SUDO[@]}" systemctl set-default graphical.target >/dev/null

    # Keep the packages that define the desired desktop explicitly manual.
    "${SUDO[@]}" apt-mark manual task-gnome-desktop gdm3 >/dev/null

    echo
    echo "GNOME installation is complete."
    echo "KDE has NOT been removed yet; this is intentional."
    echo
    echo "Configured display manager:"
    cat /etc/X11/default-display-manager 2>/dev/null || true
    echo
    echo "Next step:"
    echo "  sudo reboot"
    echo
    echo "After reboot, verify GNOME works. Only then run:"
    echo "  $0 --remove-kde"
}

remove_kde() {
    if ! dpkg-query -W -f='${db:Status-Abbrev}' gdm3 2>/dev/null \
        | grep -q '^ii'; then
        echo "ERROR: gdm3 is not installed. Run the normal conversion first." >&2
        exit 1
    fi

    if [[ "$(cat /etc/X11/default-display-manager 2>/dev/null || true)" \
        != "/usr/sbin/gdm3" ]]; then
        echo "ERROR: GDM is not the configured default display manager." >&2
        echo "Verify GNOME first, then rerun the cleanup." >&2
        exit 1
    fi

    backup_state

    KDE_CANDIDATES=(
        task-kde-desktop
        kde-standard
        kde-plasma-desktop
        plasma-desktop
        sddm
    )

    INSTALLED=()
    for pkg in "${KDE_CANDIDATES[@]}"; do
        if dpkg-query -W -f='${db:Status-Abbrev}' "${pkg}" 2>/dev/null \
            | grep -q '^ii'; then
            INSTALLED+=("${pkg}")
        fi
    done

    echo
    if [[ ${#INSTALLED[@]} -eq 0 ]]; then
        echo "No high-level KDE packages from the conservative cleanup list are installed."
    else
        echo "Removing these high-level KDE desktop packages:"
        printf '  %s\n' "${INSTALLED[@]}"
        echo
        "${SUDO[@]}" apt-get purge -y "${INSTALLED[@]}"
    fi

    "${SUDO[@]}" systemctl enable --force gdm3.service >/dev/null 2>&1 || true
    printf '/usr/sbin/gdm3\n' \
        | "${SUDO[@]}" tee /etc/X11/default-display-manager >/dev/null
    "${SUDO[@]}" apt-mark manual task-gnome-desktop gdm3 >/dev/null

    REVIEW_FILE="${HOME}/debian-gnome-autoremove-review.txt"

    echo
    echo "Generating an autoremove DRY RUN for manual review..."
    apt-get --dry-run autoremove | tee "${REVIEW_FILE}"

    echo
    echo "KDE high-level cleanup is complete."
    echo "No automatic dependency purge was performed."
    echo "Review this file before ever running apt autoremove:"
    echo "  ${REVIEW_FILE}"
}

case "${MODE}" in
    install)
        install_gnome
        ;;
    remove-kde)
        remove_kde
        ;;
esac
