#!/bin/bash
#===============================================================================
# mkfs-guarded-harness — audit-D1 test harness for configs/felhom-mkfs-guarded.sh.
#
# Runs the REAL wrapper against throwaway loop devices with:
#   - a PATH-shimmed `lsblk` that fakes the member FSTYPE signal (FIXTURE_FSTYPE),
#   - a private mount namespace (unshare -m) that bind-mounts a RECORDER over
#     /usr/sbin/mkfs.ext4 — so a wrapper that decides to format provably "formats"
#     (the recorder logs the argv) while NO real mkfs can ever run, and
#   - /dev/null bind-mounted over pvs for the pvs-absent case.
#
# Nothing real is formatted; nothing leaks outside the namespace; the loop files
# are throwaway temps. Run as root on a Linux host (losetup/unshare needed).
#
# Usage: mkfs-guarded-harness.sh <path-to-wrapper-under-test>
# Exit 0 = all cases behave like the FIXED wrapper should. Running it against the
# pre-fix wrapper is the red-proof: the member/RO cases will FAIL (recorder fired).
#===============================================================================
set -euo pipefail

WRAPPER="${1:?usage: mkfs-guarded-harness.sh <wrapper>}"
WRAPPER="$(readlink -f "$WRAPPER")"
[[ -r "$WRAPPER" ]] || { echo "no wrapper at $WRAPPER" >&2; exit 2; }
[[ "$(id -u)" == 0 ]] || { echo "must run as root (losetup/unshare)" >&2; exit 2; }

WORK="$(mktemp -d /tmp/mkfs-harness.XXXXXX)"
LOOP=""; LOOP_RO=""
cleanup() {
  [[ -n "$LOOP"    ]] && losetup -d "$LOOP"    2>/dev/null || true
  [[ -n "$LOOP_RO" ]] && losetup -d "$LOOP_RO" 2>/dev/null || true
  rm -rf "$WORK"
}
trap cleanup EXIT

# --- throwaway loop devices (a plain RW one + a kernel-read-only one) ---
truncate -s 64M "$WORK/plain.img"
truncate -s 64M "$WORK/ro.img"
LOOP="$(losetup -f --show "$WORK/plain.img")"
LOOP_RO="$(losetup -f --show -r "$WORK/ro.img")"
echo "loop devices: rw=$LOOP ro=$LOOP_RO"

# --- PATH shim: lsblk fakes only the `-nro FSTYPE` read when FIXTURE_FSTYPE is set ---
mkdir -p "$WORK/shim"
cat > "$WORK/shim/lsblk" <<'EOF'
#!/bin/bash
if [[ -n "${FIXTURE_FSTYPE:-}" && "${1:-}" == "-nro" && "${2:-}" == "FSTYPE" ]]; then
  echo "$FIXTURE_FSTYPE"
  exit 0
fi
exec /usr/bin/lsblk "$@"
EOF
chmod 0755 "$WORK/shim/lsblk"

# --- the mkfs recorder bound over /usr/sbin/mkfs.ext4 inside the namespace ---
cat > "$WORK/fake-mkfs" <<'EOF'
#!/bin/bash
echo "mkfs.ext4 $*" >> "$MKFS_MARKER"
exit 0
EOF
chmod 0755 "$WORK/fake-mkfs"

# run_case <name> <dev> <fixture_fstype> <hide_pvs 0|1> <want refuse|format> <want_msg_substr>
pass=0; fail=0
run_case() {
  local name="$1" dev="$2" fixture="$3" hidepvs="$4" want="$5" msg="$6"
  local marker="$WORK/marker.$RANDOM"; rm -f "$marker"
  local hide_cmds=""
  if [[ "$hidepvs" == 1 ]]; then
    for p in /usr/sbin/pvs /sbin/pvs; do
      [[ -e "$p" ]] && hide_cmds+="mount --bind /dev/null $p; "
    done
  fi
  set +e
  out="$(unshare -m bash -c "
    set -e
    mount --bind '$WORK/fake-mkfs' /usr/sbin/mkfs.ext4
    $hide_cmds
    export PATH='$WORK/shim':\$PATH MKFS_MARKER='$marker' FIXTURE_FSTYPE='$fixture'
    exec bash '$WRAPPER' '$dev' ext4
  " 2>&1)"
  rc=$?
  set -e
  local fired=no; [[ -s "$marker" ]] && fired=yes
  local verdict=FAIL
  if [[ "$want" == refuse ]]; then
    [[ $rc -ne 0 && "$fired" == no && "$out" == *"$msg"* ]] && verdict=PASS
  else
    [[ $rc -eq 0 && "$fired" == yes && "$(cat "$marker")" == *"$dev"* ]] && verdict=PASS
  fi
  if [[ "$verdict" == PASS ]]; then pass=$((pass+1)); else fail=$((fail+1)); fi
  printf '%-4s %-38s rc=%-3s mkfs-fired=%-3s want=%s\n' "$verdict" "$name" "$rc" "$fired" "$want"
  [[ "$verdict" == FAIL ]] && printf '      output: %s\n' "$out"
  return 0
}

echo "--- wrapper under test: $WRAPPER ---"
run_case "refuse zfs_member"        "$LOOP"    "zfs_member"        0 refuse "zfs_member"
run_case "refuse linux_raid_member" "$LOOP"    "linux_raid_member" 0 refuse "linux_raid_member"
run_case "refuse crypto_LUKS"       "$LOOP"    "crypto_LUKS"       0 refuse "crypto_LUKS"
run_case "refuse swap"              "$LOOP"    "swap"              0 refuse "swap"
run_case "refuse LVM2_member"       "$LOOP"    "LVM2_member"       0 refuse "LVM"
run_case "refuse read-only device"  "$LOOP_RO" ""                  0 refuse "read-only"
run_case "pvs-hidden still catches LVM" "$LOOP" "LVM2_member"      1 refuse "LVM"
run_case "plain blank disk formats" "$LOOP"    ""                  0 format ""

echo "--- $pass passed, $fail failed ---"
[[ $fail -eq 0 ]]
