#!/bin/bash
# Usage: linuxdoors-plasma68-vnc [WxH] [vnc-password]
#        linuxdoors-plasma68-vnc --stop
# Starts (or reuses) a headless Plasma 6.8 session for the calling user and
# serves it with krfb on 127.0.0.1:5901. Run as the target user inside a real
# user session (XDG_RUNTIME_DIR + DBUS_SESSION_BUS_ADDRESS set), e.g. over
# x2go's SSH connection. No password argument = keep the current one.
set -e
P=/opt/plasma68
UNIT=plasma68-vnc
if [ "$1" = "--stop" ]; then
  if systemctl --user is-active --quiet "$UNIT.service" 2>/dev/null; then
    systemctl --user stop "$UNIT.service" 2>&1 || echo "FAILED_TO_STOP: $UNIT.service"
  fi
  exit 0
fi
GEOM="${1:-1920x1080}"
PASS="${2:-}"
case "$GEOM" in
  [0-9]*x[0-9]*) case "$GEOM" in *[!0-9x]*) echo "linuxdoors-plasma68-vnc: bad size $GEOM" >&2; exit 2;; esac ;;
  *) echo "linuxdoors-plasma68-vnc: bad size $GEOM (want WxH)" >&2; exit 2 ;;
esac
if [ -z "$XDG_RUNTIME_DIR" ] || [ -z "$DBUS_SESSION_BUS_ADDRESS" ]; then
  echo "linuxdoors-plasma68-vnc: run this inside a real user session" \
       "(XDG_RUNTIME_DIR/DBUS_SESSION_BUS_ADDRESS must be set)" >&2
  exit 1
fi
# PipeWire carries the screen from KWin to krfb; wireplumber links the streams.
systemctl --user start pipewire.socket pipewire.service >/dev/null 2>&1 || true
systemctl --user start wireplumber.service >/dev/null 2>&1 || true

STATE="$XDG_RUNTIME_DIR/linuxdoors-plasma68-vnc"
mkdir -p "$STATE"; chmod 700 "$STATE"
OLDPASS="$(cat "$STATE/password" 2>/dev/null || true)"
if [ -n "$PASS" ]; then (umask 077; printf '%s' "$PASS" > "$STATE/password"); fi
if [ ! -s "$STATE/password" ]; then
  echo "linuxdoors-plasma68-vnc: no VNC password given and none set yet" >&2
  exit 1
fi

RUNNING=""
if systemctl --user is-active --quiet "$UNIT.service" 2>/dev/null; then
  RUNNING="$(cat "$STATE/geometry" 2>/dev/null || true)"
fi
if [ "$RUNNING" != "$GEOM" ]; then
  # new session, or a different size: KWin's virtual output size is fixed
  # at start, so a resize restarts the session at the new size.
  systemctl --user stop "$UNIT.service" >/dev/null 2>&1 || true
  systemctl --user reset-failed "$UNIT.service" >/dev/null 2>&1 || true
  echo "$GEOM" > "$STATE/geometry"
  rm -f "$STATE/krfb-ready"
  systemd-run --user --unit="$UNIT" --collect --property=KillMode=control-group \
    "$P/libexec/linuxdoors-plasma68-session" "$GEOM" >/dev/null
elif [ -n "$PASS" ] && [ "$PASS" != "$OLDPASS" ]; then
  # same session, new password: restart only krfb (its runner loop rereads it)
  rm -f "$STATE/krfb-ready"
  pkill -u "$(id -u)" -f '^[^ ]*/krfb --nodialog' >/dev/null 2>&1 || true
fi

# wait until krfb is listening, so the client's tunnel has something to reach.
# The first start can take over a minute: the KDE portal waits ~50 s for a
# notification service before it hands krfb its screencast.
for i in $(seq 1 240); do
  [ -e "$STATE/krfb-ready" ] && break
  systemctl --user is-active --quiet "$UNIT.service" || break
  sleep 1
done
if [ -e "$STATE/krfb-ready" ]; then
  echo "Plasma 6.8 is running headless and reachable over VNC on 127.0.0.1:5901."
else
  echo "linuxdoors-plasma68-vnc: the session did not come up; see: journalctl --user -u $UNIT" >&2
  journalctl --user -u "$UNIT" -n 25 --no-pager >&2 2>/dev/null || true
  exit 1
fi
