#!/usr/bin/env bash
# Hermetic coverage for the two deadline branches added after boxes were needlessly
# reverted: a reboot-proven host cancels, and an unhealthy snapshot is refused.  It
# uses a disposable root and fake systemctl, never a real host or this machine's /etc.
set -euo pipefail

HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPT="$HERE/../deadman/buildbox-deadman"
WORK="$(mktemp -d)"
trap 'rm -rf "$WORK"' EXIT
ROOT="$WORK/root"; STATE="$WORK/state"; UNITS="$WORK/units"; BIN="$WORK/bin"; BOOT="$WORK/boot"
mkdir -p "$ROOT/etc/ssh" "$ROOT/etc/systemd" "$ROOT/etc/sysctl.d" "$STATE" "$UNITS" "$BIN"
printf 'original\n' >"$ROOT/etc/fstab"
printf '#!/bin/sh\nexit 0\n' >"$BIN/systemctl"
chmod 755 "$BIN/systemctl"

pass=0; fail=0
ok() { pass=$((pass + 1)); printf 'ok   %s\n' "$1"; }
bad() { fail=$((fail + 1)); printf 'FAIL %s\n' "$1"; }
CLOCK=200

run() {
  PATH="$BIN:$PATH" BUILDBOX_DEADMAN_ROOT="$ROOT" BUILDBOX_DEADMAN_STATE_DIR="$STATE" \
    BUILDBOX_DEADMAN_UNIT_DIR="$UNITS" BUILDBOX_DEADMAN_BOOT_ID_FILE="$BOOT" \
    BUILDBOX_DEADMAN_SELF="$WORK/buildbox-deadman" BUILDBOX_DEADMAN_NOW="$CLOCK" \
    BUILDBOX_DEADMAN_DOORS_OK="$1" BUILDBOX_DEADMAN_EFFECTIVE_UID=0 "$SCRIPT" "${@:2}"
}

# A host which has rebooted and still has a door has proven the change.  The deadline
# must stand down, not restore its old snapshot over a working configuration.
printf 'before\n' >"$BOOT"
run yes arm --id survived --deadline-sec 60 >/dev/null
printf 'after\n' >"$BOOT"
CLOCK=300
run yes check >"$WORK/cancel.out"
grep -qx 'DEADMAN cancelled id=survived reason=survived-reboot' "$WORK/cancel.out" \
  && ok 'reboot-proven host is cancelled' || bad 'reboot-proven host was not cancelled'
[ ! -e "$STATE/state.json" ] && ok 'cancel removes active state' || bad 'cancel left active state'

# Reset the disposable state, then arm while no local sshd door exists.  The captured
# snapshot cannot be last-known-good, so the deadline must refuse rather than restore it.
rm -rf "$STATE"; mkdir -p "$STATE"
printf 'same-boot\n' >"$BOOT"
CLOCK=200
run no arm --id unhealthy --deadline-sec 60 >/dev/null
CLOCK=300
run no check >"$WORK/refuse.out"
grep -qx 'DEADMAN refused id=unhealthy reason=unhealthy-snapshot' "$WORK/refuse.out" \
  && ok 'unhealthy snapshot is refused' || bad 'unhealthy snapshot was not refused'
[ -f "$STATE/refused-unhealthy.json" ] && ok 'refusal retains evidence' || bad 'refusal lost evidence'

printf '\n%d passed, %d failed\n' "$pass" "$fail"
[ "$fail" = 0 ]
