#!/usr/bin/env bash
# dangerlab — inspect the clone pool. Tests go through dangerlab-run, never through here.
source /home/user/dangerlab/dangerlab-lib.sh

usage() {
  cat <<'EOF'
dangerlab slots            slot occupancy, one line per slot
dangerlab status           template integrity + pool cgroup readback + slots
dangerlab reap             collect abandoned clones now (the timer does this every minute)
dangerlab verify           check the frozen template against its sha256 pin
EOF
}

slot_owner_free() { # slot -> 0 when no live owner holds the lock
  local lock; lock=$(slot_lock "$1")
  [[ -e "$lock" ]] || return 0
  ( exec 9>"$lock"; flock -n 9 ) >/dev/null 2>&1
}

cmd_slots() {
  local k dom state deadline keep owner now
  now=$(date +%s)
  for k in $(slot_seq); do
    dom=$(slot_dom "$k")
    state=$(vm_state "$dom"); state=${state:-undefined}
    deadline=$(cat "$(slot_deadline "$k")" 2>/dev/null || echo -)
    keep=$(cat "$(slot_keep "$k")" 2>/dev/null || echo -)
    if slot_owner_free "$k"; then owner=free; else owner=held; fi
    printf 'slot%s domain=%-10s owner=%-4s overlay=%s deadline=%s keep=%s\n' \
      "$k" "$state" "$owner" \
      "$([[ -f $(slot_overlay "$k") ]] && echo yes || echo no)" \
      "$([[ $deadline == - ]] && echo - || echo $(( deadline - now ))s)" \
      "$([[ $keep == - ]] && echo - || echo $(( keep - now ))s)"
  done
}

cmd_status() {
  cmd_verify
  printf -- '--- pool cgroup ---\n'
  local pool=/sys/fs/cgroup/machine.slice/machine-dangerlab.slice f
  for f in cpu.max memory.max memory.swap.max pids.max; do
    printf '%-16s %s\n' "$f" "$(sudo -n cat "$pool/$f" 2>/dev/null || echo '<absent>')"
  done
  printf -- '--- slots ---\n'
  cmd_slots
}

cmd_verify() {
  base_verify
  printf 'template %s verified against %s\n' "$BASE" "$BASE_SUM"
  printf 'template mode %s (never booted, never written)\n' "$(stat -c %A "$BASE")"
}

case "${1:-}" in
  slots)  cmd_slots ;;
  status) cmd_status ;;
  reap)   exec /home/user/dangerlab/dangerlab-reap ;;
  verify) cmd_verify ;;
  *) usage >&2; exit 2 ;;
esac
