#!/usr/bin/env bash

# The desktop installs before anything that is allowed to fail.
#
# install-packages runs under `set -euo pipefail`, and the Hyprland block used
# to sit near the bottom of it, below a codec swap, two group updates and a
# GStreamer glob. Any one of those exiting non-zero ended the stage where it
# stood. On a machine whose spin never shipped ffmpeg-free, the swap failed, the
# stage died, and the install finished reporting one red line among twenty
# minutes of scrollback -- with no Hyprland on the disk at all.
#
# The rule that prevents it: anything that can fail for a reason outside this
# repository goes BELOW the desktop, and goes through `soft`. What is left above
# the desktop is only what the desktop needs.
#
# This pins the order, not the individual commands, because the next fragile
# thing somebody adds will not be a codec swap.

set -uo pipefail

repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
installer="$repo_dir/setup/scripts/install-packages"

findings=()
note() { findings+=("$1"); }

[[ -x "$installer" ]] || { printf 'desktop first contract: %s is not executable\n' "$installer" >&2; exit 1; }

line_of() { grep -n "$1" "$installer" | head -1 | cut -d: -f1; }

hyprland_at="$(line_of '^HYPR_FILE=')"
[[ -n "$hyprland_at" ]] || { printf 'desktop first contract: no Hyprland block found\n' >&2; exit 1; }

# ── Nothing fragile above the desktop ───────────────────────────────────────
#
# Named individually rather than by pattern: each is a command whose failure is
# survivable, and each one above the Hyprland block is a machine that boots to
# nothing.

for fragile in 'dnf swap' 'groupupdate' 'group upgrade' 'gstreamer1-plugins' \
               'flatpak install' 'nvm install' 'curl -fsSL'; do
    while read -r at; do
        (( at < hyprland_at )) \
            && note "'$fragile' runs at line $at, above the desktop at line $hyprland_at"
    done < <(grep -n -- "$fragile" "$installer" | grep -v '^\s*#' | cut -d: -f1)
done

# ── Everything fragile is actually tolerated ────────────────────────────────
#
# Being below the desktop is only half of it. A bare `dnf swap` below the
# Hyprland block still kills every step after it -- the flatpaks, the extras
# somebody explicitly chose.

# Comments dropped and backslash continuations joined, so a `soft` invocation
# wrapped across three lines reads as the one command it is.
uncommented() { grep -vE '^\s*#' "$installer" | sed -e :a -e '/\\$/N; s/\\\n\s*/ /; ta'; }

while read -r command; do
    uncommented | grep -q "soft .*$command" \
        || note "'$command' runs without soft, so its failure still ends the stage"
done <<'FRAGILE'
dnf swap -y 'ffmpeg-free'
dnf swap -y mesa-va-drivers
groupupdate
group upgrade
gstreamer1-plugins
flatpak install -y flathub $FLATPAK_PACKAGES
FRAGILE

grep -q '^soft()' "$installer" \
    || note 'install-packages defines no soft helper, so nothing can be tolerated deliberately'

# ── The desktop failing is still fatal, and still said out loud ─────────────
#
# The inverse mistake: making everything survivable turns a machine with no
# desktop into a run that reports success.

python3 - "$installer" "$hyprland_at" <<'PY' || note 'a missing Hyprland does not stop the stage'
import sys
lines = open(sys.argv[1], encoding="utf-8").read().splitlines()
start = int(sys.argv[2])
after = "\n".join(lines[start:start + 40])
if "rpm -q hyprland" not in after or "exit 1" not in after:
    raise SystemExit(1)
PY

uncommented | grep -q 'soft .*HYPR_PACKAGES' \
    && note 'the Hyprland install is tolerated, so a machine with no desktop reports success'

# ── Soft failures are reported ──────────────────────────────────────────────

grep -q 'softly_failed' "$installer" \
    || note 'nothing collects what was stepped over, so a tolerated failure is a silent one'

python3 - "$installer" <<'PY' || note 'the list of stepped-over steps is never printed'
import sys
text = open(sys.argv[1], encoding="utf-8").read()
tail = text[text.rindex("softly_failed"):]
if "printf" not in tail and "log" not in tail:
    raise SystemExit(1)
PY

if (( ${#findings[@]} > 0 )); then
    mapfile -t findings < <(printf '%s\n' "${findings[@]}" | sort -u)
    printf 'desktop first contract: %d finding(s)\n' "${#findings[@]}" >&2
    printf '  - %s\n' "${findings[@]}" >&2
    exit 1
fi

printf 'desktop first contract: PASS (desktop at line %s, everything fragile below it)\n' "$hyprland_at"
