#!/usr/bin/env bash
# Both-ways proof for the deck-podman sandbox wrapper.
#
# The defect: rootless podman invoked from inside an agent sandbox cannot build a
# user namespace, fails, and leaks a podman-pause-*.scope plus a catatonit on every
# attempt. Its own error text recommends `podman system migrate` (which stops every
# running container) and a reboot. The leak assertion below is the regression that
# matters — a test that only checks `podman images` exits 0 would not have caught it.
set -uo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
WRAP="$ROOT/modules/workstation/bin/deck-podman"
PASS=0; FAIL=0; SKIP=0
ok()   { PASS=$((PASS+1)); printf 'ok   %s\n' "$1"; }
no()   { FAIL=$((FAIL+1)); printf 'FAIL %s\n     %s\n' "$1" "$2"; }
skip() { SKIP=$((SKIP+1)); printf 'skip %s (%s)\n' "$1" "$2"; }

[[ -x "$WRAP" ]] || { echo "FAIL wrapper not executable: $WRAP"; exit 1; }

mapped_uids() {
  local total=0 _in _out count
  while read -r _in _out count; do
    [[ -n "${count:-}" ]] || continue
    total=$(( total + count ))
  done < /proc/self/uid_map
  printf '%s' "$total"
}
CONFINED=no
[[ "$(mapped_uids)" -le 1 ]] && CONFINED=yes

pause_scopes() {
  local d="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/systemd/transient"
  [[ -d "$d" ]] || { printf '0'; return; }
  find "$d" -maxdepth 1 -name 'podman-pause-*.scope' 2>/dev/null | wc -l
}

# --- guards that must fire regardless of podman being installed ---

# The sandbox overlays /tmp with a private upperdir. A podman running outside the
# sandbox would resolve the same path to something else entirely.
if [[ "$CONFINED" == yes ]]; then
  out="$(cd /tmp && "$WRAP" images 2>&1)"; rc=$?
  if [[ $rc -ne 0 && "$out" == *"sandbox /tmp is private"* ]]; then
    ok "refuses to run with a sandbox-private cwd"
  else
    no "refuses to run with a sandbox-private cwd" "rc=$rc out=$out"
  fi

  out="$("$WRAP" build /tmp/some-context 2>&1)"; rc=$?
  if [[ $rc -ne 0 && "$out" == *"sandbox-private /tmp"* ]]; then
    ok "refuses a /tmp path argument"
  else
    no "refuses a /tmp path argument" "rc=$rc out=$out"
  fi

  out="$("$WRAP" run -it alpine sh 2>&1)"; rc=$?
  if [[ $rc -ne 0 && "$out" == *"interactive terminal cannot be forwarded"* ]]; then
    ok "refuses an interactive tty subcommand instead of silently dropping the pty"
  else
    no "refuses an interactive tty subcommand" "rc=$rc out=$out"
  fi

  # `-t` on build is a tag, not a tty: the tty guard must not fire here.
  out="$("$WRAP" build -t deck-podman-test-nonexistent /nonexistent-context-dir 2>&1)"
  if [[ "$out" != *"interactive terminal cannot be forwarded"* ]]; then
    ok "does not mistake 'build -t <tag>' for a tty request"
  else
    no "does not mistake 'build -t <tag>' for a tty request" "$out"
  fi
else
  skip "sandbox guards" "not running confined; guards are unreachable"
fi

# A wrapper that resolves the wrapped name through PATH without excluding its own
# directory re-enters itself. That shape fork-bombed this workstation before.
SHIMDIR="$(mktemp -d)"
trap 'rm -rf "$SHIMDIR"' EXIT
ln -s "$WRAP" "$SHIMDIR/podman"
out="$(PATH="$SHIMDIR:$PATH" timeout 20 "$WRAP" --version 2>&1)"; rc=$?
if [[ $rc -ne 124 ]]; then
  ok "does not re-enter itself when a 'podman' symlink to it is first on PATH"
else
  no "does not re-enter itself via PATH" "timed out — wrapper recursed"
fi

if [[ "$CONFINED" == yes ]]; then
  cat > "$SHIMDIR/systemd-run" <<'EOF'
#!/usr/bin/env bash
[[ " $* " == *" -p KillMode=process "* ]]
EOF
  chmod +x "$SHIMDIR/systemd-run"
  PATH="$SHIMDIR:$PATH" DECK_PODMAN_REAL=/bin/true "$WRAP" version >/dev/null 2>&1
  rc_killmode=$?
  if [[ $rc_killmode -eq 0 ]]; then
    ok "preserves rootless networking children with KillMode=process"
  else
    no "preserves rootless networking children" "systemd-run did not receive -p KillMode=process"
  fi
else
  skip "KillMode process property" "not running confined; systemd-run path is unreachable"
fi

# --- behaviour against the real podman ---

if ! command -v podman >/dev/null 2>&1; then
  skip "podman behaviour" "podman not installed"
else
  before="$(pause_scopes)"

  out="$("$WRAP" version --format '{{.Client.Version}}' 2>&1)"; rc=$?
  if [[ $rc -eq 0 && "$out" =~ ^[0-9]+\. ]]; then
    ok "reaches podman and returns a real answer (version=$out, confined=$CONFINED)"
  else
    no "reaches podman" "rc=$rc out=$out"
  fi

  "$WRAP" images >/dev/null 2>&1
  rc_images=$?
  if [[ $rc_images -eq 0 ]]; then ok "podman images succeeds through the wrapper"
  else no "podman images succeeds through the wrapper" "rc=$rc_images"; fi

  "$WRAP" ps -a >/dev/null 2>&1
  rc_ps=$?
  if [[ $rc_ps -eq 0 ]]; then ok "podman ps -a succeeds through the wrapper"
  else no "podman ps -a succeeds through the wrapper" "rc=$rc_ps"; fi

  # podman exits 125 on an unknown subcommand; the wrapper must not flatten it.
  "$WRAP" no-such-subcommand >/dev/null 2>&1
  rc_bad=$?
  if [[ $rc_bad -eq 125 ]]; then ok "propagates podman's exit code unchanged (125)"
  else no "propagates podman's exit code" "expected 125 got $rc_bad"; fi

  printf 'stdin-probe\n' | "$WRAP" version >/dev/null 2>&1
  rc_stdin=$?
  if [[ $rc_stdin -eq 0 ]]; then ok "survives having stdin attached to a pipe"
  else no "survives having stdin attached to a pipe" "rc=$rc_stdin"; fi

  after="$(pause_scopes)"
  if [[ "$before" == "$after" ]]; then
    ok "leaks no podman-pause scope across the run (count stayed $after)"
  else
    no "leaks no podman-pause scope" "scopes went $before -> $after"
  fi
fi

printf '\n%d passed, %d failed, %d skipped\n' "$PASS" "$FAIL" "$SKIP"
[[ $FAIL -eq 0 ]]
