#!/bin/bash
# =============================================================================
# migrate-to-greetd.sh — switch an existing install to Plymouth + greetd/ReGreet
# =============================================================================
# Migrates a machine that currently boots lightdm / ly / GDM / SDDM / LXDM (or a
# bare greetd+tuigreet) to this repo's current default boot experience:
#
#     Plymouth skull splash  →  greetd + ReGreet + cage (Wayland-native,
#                               cyberqueer-themed graphical greeter)
#
# This is the Wayland counterpart to migrate-to-lightdm.sh. ReGreet runs on
# wlroots (inside a cage kiosk), so it drives every output natively (no blank
# monitor) and hands input straight to the Wayland session with no Xorg→Wayland
# VT handover race — the reason The-Core moved off the LightDM (Xorg) greeter.
#
# What it does:
#   1. Detects the currently-configured display manager(s).
#   2. Disables every known greeter EXCEPT greetd — for the NEXT boot only. It
#      does NOT stop your running session, so you stay logged in until you
#      reboot yourself.
#   3. Runs the greetd-regreet module (installs greetd + greetd-regreet + cage,
#      deploys the greetd/ReGreet config, the cyberqueer regreet.css skin, the
#      skull fallback background + wallpaper-sync units, sets up PAM/FIDO,
#      disables lightdm/ly@tty1/getty@tty1, and enables greetd.service).
#   4. Runs the plymouth module (skull splash, initramfs + GRUB cmdline) unless
#      --no-plymouth is given.
#
# greetd.service is the TARGET, so it is never disabled here: a machine already
# on a bare greetd+tuigreet is simply reconfigured to run ReGreet instead.
#
# It reuses the real module scripts under optional-Modules/apps/ so there is no
# duplicated install logic — this tool only handles detection, teardown of the
# OLD display manager, and orchestration.
#
# Safe to re-run (idempotent). Reboot to complete the switch.
#
# Usage:
#   migrate-to-greetd.sh [--yes] [--no-plymouth] [--dry-run] [--help]
#     -y, --yes          Skip the confirmation prompt (required for non-TTY runs)
#         --no-plymouth  Migrate the display manager only; leave Plymouth alone
#     -n, --dry-run      Print what would happen; change nothing
#     -h, --help         Show this help and exit
# =============================================================================
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SETUP_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
APPS="$SETUP_DIR/modules/optional-Modules/apps"

# Shared helpers: log / skip / warn / err, and best-effort disable_service.
source "$SETUP_DIR/modules/lib/logging.sh"

# ── Argument parsing ──────────────────────────────────────────────────────────
ASSUME_YES=0
DO_PLYMOUTH=1
DRY_RUN=0

usage() {
    cat <<'EOF'
migrate-to-greetd.sh — switch this machine to Plymouth + greetd/ReGreet (cyberqueer)

Disables the current display manager (lightdm / ly / GDM / SDDM / LXDM / …) for
the next boot, installs and themes the greetd + ReGreet (Wayland) greeter, and
sets up the Plymouth splash. Your running session is left untouched; reboot to
complete the switch.

Usage:
  migrate-to-greetd.sh [--yes] [--no-plymouth] [--dry-run] [--help]
    -y, --yes          Skip the confirmation prompt (required for non-TTY runs)
        --no-plymouth  Migrate the display manager only; leave Plymouth alone
    -n, --dry-run      Print what would happen; change nothing
    -h, --help         Show this help and exit
EOF
}

while [[ $# -gt 0 ]]; do
    case "$1" in
        -y|--yes)        ASSUME_YES=1 ;;
        --no-plymouth)   DO_PLYMOUTH=0 ;;
        -n|--dry-run)    DRY_RUN=1 ;;
        -h|--help)       usage; exit 0 ;;
        *) err "Unknown argument: $1"; echo "Try --help." >&2; exit 2 ;;
    esac
    shift
done

# In dry-run, describe an action instead of doing it. In real mode, run it.
run() {
    if (( DRY_RUN )); then
        printf '[dry-run] would run: %s\n' "$*"
    else
        "$@"
    fi
}

# ── Known display managers ────────────────────────────────────────────────────
# Every greeter/DM unit this tool knows how to turn off. greetd is the TARGET,
# so it never appears here (a bare greetd+tuigreet install is reconfigured, not
# disabled). ly is a template unit (ly@tty1) but some setups use the plain
# ly.service alias, so both are listed.
OTHER_DMS=(
    "lightdm.service"
    "ly@tty1.service" "ly.service"
    "gdm.service" "gdm3.service"
    "sddm.service"
    "lxdm.service"
    "xdm.service"
    "slim.service"
    "lemurs.service"
    "emptty.service"
)

# ── 1. Detect what is configured now ──────────────────────────────────────────
log "Detecting the current display manager configuration..."

# The canonical "which DM boots" pointer is the display-manager.service symlink.
# Use plain readlink to get the intended target name even if the link is broken;
# a self-referential/absent target means no real DM is configured there.
primary_dm=""
if dm_link="$(readlink /etc/systemd/system/display-manager.service 2>/dev/null)"; then
    dm_link="$(basename "$dm_link")"
    [[ "$dm_link" != "display-manager.service" ]] && primary_dm="$dm_link"
fi

# Also probe every known unit directly — ly-based installs often have no
# display-manager.service symlink, they just enable ly@tty1 on tty1.
enabled_dms=()
for unit in "${OTHER_DMS[@]}"; do
    state="$(systemctl is-enabled "$unit" 2>/dev/null || true)"
    [[ "$state" == "enabled" || "$state" == "alias" || "$state" == "enabled-runtime" ]] \
        && enabled_dms+=("$unit")
done

# `is-enabled` on an absent unit both prints "not-found" and exits non-zero;
# capture with `|| true` (never `|| echo`, which would concatenate two lines)
# and normalise the "not installed" cases to one label.
greetd_state="$(systemctl is-enabled greetd.service 2>/dev/null || true)"
[[ -z "$greetd_state" || "$greetd_state" == "not-found" ]] && greetd_state="not-installed"

echo
echo "  Current display-manager.service : ${primary_dm:-<none>}"
if (( ${#enabled_dms[@]} )); then
    echo "  Enabled greeter units           : ${enabled_dms[*]}"
else
    echo "  Enabled greeter units           : <none detected>"
fi
echo "  greetd.service                  : $greetd_state"
echo "  Plymouth migration              : $( ((DO_PLYMOUTH)) && echo 'yes' || echo 'skipped (--no-plymouth)')"
echo

if (( ${#enabled_dms[@]} == 0 )) && [[ "$greetd_state" == "enabled" ]]; then
    log "greetd already appears to be the active greeter — re-running to install/refresh ReGreet + theme."
fi

# ── 2. Confirm ────────────────────────────────────────────────────────────────
# This changes what greets you at the NEXT boot. Require an explicit yes unless
# --yes was given; on a non-interactive stdin, --yes is mandatory.
if (( ! ASSUME_YES )); then
    if [[ ! -t 0 ]]; then
        err "Non-interactive shell and --yes not given — refusing to change the display manager."
        exit 1
    fi
    read -r -p "Switch this machine to Plymouth + greetd/ReGreet as described above? [y/N] " reply
    case "$reply" in
        y|Y|yes|YES) ;;
        *) warn "Aborted — nothing changed."; exit 0 ;;
    esac
fi

# ── 3. Disable the OLD display managers (next boot only) ──────────────────────
# We intentionally do NOT `systemctl stop` the running greeter: that would kill
# your current graphical session. Disabling only removes it from the next boot;
# greetd.service (enabled below by the module) takes over then.
if (( ${#enabled_dms[@]} )); then
    log "Disabling old display manager(s) for the next boot: ${enabled_dms[*]}"
    for unit in "${enabled_dms[@]}"; do
        run disable_service "$unit"
    done
else
    skip "No competing display managers enabled — nothing to disable."
fi

# ── 4. Install + theme + enable greetd/ReGreet (delegated to the module) ──────
# greetd-regreet.sh installs greetd + greetd-regreet + cage, deploys the greetd
# config + ReGreet config + cyberqueer regreet.css skin + skull background,
# wires up PAM/FIDO and the wallpaper-sync units, disables lightdm/ly@tty1/
# getty@tty1, and enables greetd.service. Running it here keeps a single source
# of truth.
log "Setting up greetd + ReGreet via the greetd-regreet module..."
run bash "$APPS/greetd-regreet.sh"

# ── 5. Plymouth splash (delegated to the module) ──────────────────────────────
if (( DO_PLYMOUTH )); then
    # Upgrade cleanup: the current theme is a centred skull + boot-log tail. The
    # previous version scaled the skull full-screen and drew a spinning-dot
    # throbber from dot.png. That file is now dead weight — strip it (and any
    # other stale theme assets) BEFORE re-running the module, so it is neither
    # rendered nor baked into the initramfs that plymouth.sh rebuilds.
    THEME_DIR="/usr/share/plymouth/themes/m-archy"
    for stale in "$THEME_DIR/dot.png"; do
        if [[ -e "$stale" ]]; then
            log "Removing obsolete Plymouth asset: $stale"
            run sudo rm -f "$stale"
        fi
    done

    log "Setting up the Plymouth splash via the plymouth module..."
    run bash "$APPS/plymouth.sh"
else
    skip "Skipping Plymouth setup (--no-plymouth)."
fi

# ── Done ──────────────────────────────────────────────────────────────────────
echo
if (( DRY_RUN )); then
    log "Dry run complete — no changes were made."
else
    log "Migration complete. Your current session is untouched."
    log "Reboot to boot into the Plymouth splash and the greetd/ReGreet cyberqueer greeter."
fi
