#!/usr/bin/env bash
# Sourced FIRST by every exhaustion-class test. `require_danger_lab` exits non-zero
# before the test spawns anything unless the process is inside the disposable
# dangerlab guest (Projects/0 DOCS/dangerlab.md).
#
# The predicate is positive and read from the machine, never from a name or an
# env var a caller controls:
#   - DMI sys_vendor: sysfs, unwritable by any uid; the workstation reads LENOVO.
#   - kernel hostname: read from /proc, so a `hostname` PATH shim cannot answer it.
#   - cloud-init instance-id and the lineage marker: root-owned files baked into the
#     frozen base.qcow2 by dangerlab/provision.sh, so every clone of that template
#     carries them and a rebuilt template still does.
# All four must hold. No environment variable can satisfy any of them.
#
# The lineage marker replaced a pinned machine-id: each clone mints its own machine-id
# at boot (systemd-networkd derives the DHCP client identifier from it, and clones that
# shared one were handed each other's lease), so a machine-id pin identifies one
# instance and refuses in every clone of the template it was taken from.

DANGER_LAB_DMI_VENDOR="QEMU"
DANGER_LAB_HOSTNAME="dangerlab"
DANGER_LAB_INSTANCE_ID="dangerlab-1"
DANGER_LAB_LINEAGE="dangerlab-lineage-v1 f1d0c0de-da4b-4a11-9c3f-0b7e5a2d61a7"

_danger_lab_read() {
  local file="$1" line=""
  [[ -r "$file" ]] || { printf '<unreadable:%s>' "$file"; return; }
  IFS= read -r line <"$file" 2>/dev/null || true
  printf '%s' "$line"
}

# Prints one line per fact that does not match; empty output means "in the lab".
danger_lab_mismatch() {
  local v
  v=$(_danger_lab_read /sys/class/dmi/id/sys_vendor)
  [[ "$v" == "$DANGER_LAB_DMI_VENDOR" ]] || printf 'dmi sys_vendor=%s want=%s\n' "$v" "$DANGER_LAB_DMI_VENDOR"
  v=$(_danger_lab_read /proc/sys/kernel/hostname)
  [[ "$v" == "$DANGER_LAB_HOSTNAME" ]] || printf 'kernel hostname=%s want=%s\n' "$v" "$DANGER_LAB_HOSTNAME"
  v=$(_danger_lab_read /var/lib/cloud/data/instance-id)
  [[ "$v" == "$DANGER_LAB_INSTANCE_ID" ]] || printf 'cloud-init instance-id=%s want=%s\n' "$v" "$DANGER_LAB_INSTANCE_ID"
  v=$(_danger_lab_read /etc/dangerlab-lineage)
  [[ "$v" == "$DANGER_LAB_LINEAGE" ]] || printf 'lineage=%s want=%s\n' "$v" "$DANGER_LAB_LINEAGE"
}

danger_lab_override_file() { printf '%s/.dangerlab-override' "$HOME"; }
danger_lab_override_token() { printf 'I ACCEPT DESKTOP LOCKOUT %s' "$(date +%F)"; }

_danger_lab_override_taken() {
  local file line
  file="$(danger_lab_override_file)"
  [[ -f "$file" ]] || return 1
  IFS= read -r line <"$file" || return 1
  [[ "$line" == "$(danger_lab_override_token)" ]] || return 1
  local log="${XDG_STATE_HOME:-$HOME/.local/state}/danger-guard.log"
  mkdir -p "$(dirname "$log")" 2>/dev/null || true
  printf '%s override-used test=%s pid=%s ppid=%s\n' "$(date -Is)" "$1" "$$" "$PPID" >>"$log" 2>/dev/null || true
  printf 'danger-guard: OVERRIDE TAKEN for %s — running an exhaustion-class test on this host. Logged to %s\n' \
    "$1" "$log" >&2
  return 0
}

# require_danger_lab <path-to-this-test-file>
require_danger_lab() {
  local self="${1:?require_danger_lab needs the test path}" reasons
  reasons="$(danger_lab_mismatch)"
  [[ -z "$reasons" ]] && return 0
  _danger_lab_override_taken "$self" && return 0

  local name runner
  name="$(basename -- "$self")"
  runner="$(cd "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)/run-in-lab.sh"
  {
    printf 'REFUSED: %s is exhaustion-class and runs ONLY in the dangerlab guest.\n' "$name"
    printf 'This host is not the lab:\n'
    sed 's/^/  /' <<<"$reasons"
    printf '\nRun it there instead:\n    bash %s %s\n' "$runner" "$name"
    printf '\nThat wrapper ships the payload to debian1 and runs it through dangerlab-run,\n'
    printf 'which runs it in a single-use clone and destroys it after. See "Projects/0 DOCS/dangerlab.md".\n'
    printf 'Do NOT run it here — two workstation fork bombs came from exactly that.\n'
  } >&2
  exit 70
}
