#!/usr/bin/env bash
# Prove the container can actually do the four things it exists for, before an
# unattended agent spends an hour discovering otherwise.
#
# Every check here stands for a failure that has already happened once: a
# display that was not there, a missing numpy that looked like a logic bug, a
# /dev/shm too small for guest memory, a Vulkan stack with no ICD.
set -u
fail=0
ok()   { printf '  \033[32m✔\033[0m %s\n' "$*"; }
bad()  { printf '  \033[31m✖\033[0m %s\n' "$*"; fail=$((fail+1)); }
warn() { printf '  \033[33m!\033[0m %s\n' "$*"; }

echo "── resources ──"
# nproc shows the HOST's cores: --cpus is a quota, not a mask. Report both so
# "12 cpus" is never mistaken for 12 cpus' worth of throughput.
quota="unlimited"
if [ -r /sys/fs/cgroup/cpu.max ]; then
  read -r q p < /sys/fs/cgroup/cpu.max
  [ "$q" != max ] && quota="$(( q / p )) (quota)"
fi
echo "  cpus: $(nproc) visible, $quota"
if [ -r /sys/fs/cgroup/memory.max ]; then
  m=$(cat /sys/fs/cgroup/memory.max)
  [ "$m" = max ] && warn "memory: UNLIMITED — the half-the-box cap is not applied" \
                 || ok "memory cap: $(( m / 1024 / 1024 / 1024 )) GiB"
fi
shm=$(df -BM /dev/shm | awk 'NR==2{print $2}' | tr -d M)
# Guest memory for a 512 MB console plus the code cache does not fit in
# Docker's 64 MB default, and the symptom is an mmap error, not a disk-full one.
[ "${shm:-0}" -ge 512 ] && ok "/dev/shm: ${shm} MiB" || bad "/dev/shm only ${shm:-?} MiB — need >=512; pass --shm-size"

echo "── toolchain ──"
for t in clang clang++ cmake ninja cargo rustc python3 node claude; do
  command -v "$t" >/dev/null && ok "$t  ($("$t" --version 2>/dev/null | head -1))" || bad "$t missing"
done

echo "── python (dynamic RE) ──"
# numpy and PIL missing is the specific hole that silently disabled entities2.py
# and every image oracle in the toolkit.
for m in numpy PIL duckdb; do
  python3 -c "import $m" 2>/dev/null && ok "python: $m" || bad "python: $m MISSING"
done

echo "── display ──"
if xdpyinfo >/dev/null 2>&1; then
  ok "display $DISPLAY  ($(xdpyinfo | awk '/dimensions:/{print $2; exit}'))"
  pgrep -x openbox >/dev/null && ok "openbox running" || warn "no window manager — window geometry oracles will misread"
  out=$(screenshot /tmp/_doctor.png 2>&1) && [ -s /tmp/_doctor.png ] \
    && ok "screenshot works -> $(identify -format '%wx%h' /tmp/_doctor.png 2>/dev/null || echo ok)" \
    || bad "screenshot failed: $out"
  rm -f /tmp/_doctor.png
else
  bad "no display on ${DISPLAY:-<unset>}"
fi

echo "── vulkan ──"
if command -v vulkaninfo >/dev/null 2>&1; then
  dev=$(vulkaninfo --summary 2>/dev/null | grep -m3 -E 'deviceName' | sed 's/^ *//')
  [ -n "$dev" ] && { ok "Vulkan devices:"; echo "$dev" | sed 's/^/      /'; } \
                || bad "vulkaninfo found no device (ICD missing?)"
else
  bad "vulkaninfo missing"
fi
# Judge by what enumerated, not by whether a device node is present: an NVIDIA
# card needs the NVIDIA Container Toolkit, and /dev/dri alone does nothing.
case "${dev:-}" in
  *llvmpipe*|*lavapipe*)
    warn "SOFTWARE Vulkan only — correct but slow."
    command -v nvidia-smi >/dev/null 2>&1 \
      && warn "  host has an NVIDIA GPU: install nvidia-container-toolkit for hardware" ;;
  "") ;;
  *)  ok "hardware Vulkan" ;;
esac

echo "── project ──"
[ -d /work/xenia-canary ]    && ok "/work/xenia-canary"    || bad "/work/xenia-canary not mounted"
[ -d /work/Syplheed-Reborn ] && ok "/work/Syplheed-Reborn" || bad "/work/Syplheed-Reborn not mounted"
iso=$(find /work -maxdepth 2 -type f -iname '*.iso' -printf '%s\t%p\n' 2>/dev/null | sort -rn | head -1 | cut -f2-)
[ -n "$iso" ] && ok "ISO: $iso" || warn "no ISO under /work — run-canary needs SYLPH_ISO"
[ -d /work/sylph_extract/dat ] && ok "extracted disc (disc-gated tests will run)" \
                               || warn "no extracted disc — Reborn disc tests will SKIP"
[ -w /sylph-home/re/.claude ] && ok "~/.claude writable (token refresh works)" \
                              || warn "~/.claude not writable — Claude Code may fail to refresh auth"

echo
[ "$fail" -eq 0 ] && { echo "all good."; exit 0; }
echo "$fail check(s) failed."; exit 1
