#!/usr/bin/env bash
set -u

HERE="$(cd "$(dirname "$0")" && pwd)"
SCRIPT="$HERE/deploy-local.sh"
TMP="$(mktemp -d)"
cleanup() {
  chmod -R u+w "$TMP" 2>/dev/null || true
  rm -rf "$TMP"
}
trap cleanup EXIT

PASS=0
FAIL=0

ok() { PASS=$((PASS + 1)); printf 'ok - %s\n' "$1"; }
bad() { FAIL=$((FAIL + 1)); printf 'not ok - %s\n' "$1"; }

run_case() {
  local mode="$1"
  local collector="${2:-$1}"
  local case_dir="$TMP/$mode"
  local bin="$case_dir/bin"
  local caller="$case_dir/caller"
  local deploy="$case_dir/deploy"
  mkdir -p "$bin" "$caller/packaging" "$deploy/.git" "$deploy/packaging" \
    "$deploy/bin" "$deploy/lib/deckctl" "$deploy/lib/fleet" "$deploy/modules/workstation/manifest" \
    "$deploy/modules/buildbox" "$deploy/modules/fleet" "$deploy/modules/systray" \
    "$deploy/modules/monitor/systemd/user" \
    "$case_dir/home/.config/systemd/user/harnessd.service.d" \
    "$case_dir/home/.local/opt/overdeck/harness/current"
  touch "$case_dir/home/.config/systemd/user/harnessd.service.d/override.conf"
  touch "$case_dir/home/.local/opt/overdeck/harness/current/legacy"
  cp "$SCRIPT" "$caller/packaging/deploy-local.sh"
  cp "$HERE/../bin/deckctl" "$deploy/bin/deckctl.real"
  cat >"$deploy/bin/deckctl" <<'SH'
#!/usr/bin/env bash
[[ -f "$CHECKOUT_MARKER" ]] || exit 93
exec "$(dirname "$0")/deckctl.real" "$@"
SH
  chmod +x "$deploy/bin/deckctl"
  cp "$HERE/../lib/deckctl/sync.sh" "$deploy/lib/deckctl/sync.sh"
  cp -a "$HERE/../lib/fleet/." "$deploy/lib/fleet/"
  cp -a "$HERE/../modules/fleet/." "$deploy/modules/fleet/"
  cp "$HERE/../modules/buildbox/devtools.json" "$deploy/modules/buildbox/devtools.json"
  cp "$HERE/../modules/workstation/manifest/claude.json" "$deploy/modules/workstation/manifest/claude.json"
  cp "$HERE/../modules/workstation/manifest/bin.json" "$deploy/modules/workstation/manifest/bin.json"
  cp "$HERE/../modules/workstation/manifest/pi.json" "$deploy/modules/workstation/manifest/pi.json"
  cp -a "$HERE/../modules/workstation/pi" "$deploy/modules/workstation/pi"
  mkdir -p "$deploy/modules/gptbridge"
  printf '#!/usr/bin/env bash\nexit 0\n' >"$deploy/modules/gptbridge/install.sh"
  chmod +x "$deploy/modules/gptbridge/install.sh"
  cp "$HERE/../modules/workstation/deny.list" "$deploy/modules/workstation/deny.list"
  cp -a "$HERE/../modules/workstation/claude" "$deploy/modules/workstation/claude"
  cp "$HERE/../modules/monitor/systemd/user/agent.slice" "$deploy/modules/monitor/systemd/user/agent.slice"
  cp "$HERE/overdeck-deploy.path" "$HERE/overdeck-deploy.service" "$deploy/packaging/"
  mkdir -p "$case_dir/home/.claude"
  ln -s "$deploy/modules/workstation/claude/buildbox-hosts.json" \
    "$case_dir/home/.claude/buildbox-hosts.json"
  cat >"$deploy/modules/systray/install.py" <<'PY'
from os import environ
from pathlib import Path

with Path(environ["INSTALL_LOG"]).open("a", encoding="utf-8") as log:
    log.write(f"deploy-clone:{__file__}\n")
PY
  if [[ "$mode" == "untracked" ]]; then
    printf '#!/usr/bin/env bash\nprintf injected\\n\n' >"$deploy/modules/workstation/claude/bin/untracked-tool"
  fi
  if [[ "$mode" == "modified" ]]; then
    printf 'foreign edit\n' >>"$deploy/modules/workstation/claude/buildbox-hosts.json"
  fi
  if [[ "$mode" == "release-state" || "$mode" == "never-ready" ]]; then
    mkdir -p "$deploy/apps/web/.releases/bootstrap-fixture/server"
    touch "$deploy/apps/web/.releases/bootstrap-fixture/server/entry.mjs"
    ln -s bootstrap-fixture "$deploy/apps/web/.releases/current"
  fi
  if [[ "$mode" == "web-unchanged" || "$mode" == "web-changed" ]]; then
    mkdir -p "$deploy/apps/web/.releases/.build-deadbeef-AAAAAA/server" \
      "$deploy/apps/web/.releases/.build-deadbeef-AAAAAA/node_modules"
    touch "$deploy/apps/web/.releases/.build-deadbeef-AAAAAA/server/entry.mjs"
    ln -s .build-deadbeef-AAAAAA "$deploy/apps/web/.releases/current"
  fi
  if [[ "$mode" == "web-unchanged-dangling" ]]; then
    mkdir -p "$deploy/apps/web/.releases"
    ln -s .build-deadbeef-PRUNED "$deploy/apps/web/.releases/current"
  fi

  mkdir -p "$deploy/modules/workstation/claude/workflows/hooks" "$deploy/collector/scripts"
  touch "$deploy/collector/scripts/brief-canary.ts"
  for stub in modules/workstation/claude/bin/shim-drift-check \
    modules/workstation/claude/workflows/hooks/install-land-guard.sh \
    packaging/web-deps-verify.sh; do
    printf '#!/usr/bin/env bash\nexit 0\n' >"$deploy/$stub"
    chmod +x "$deploy/$stub"
  done
  cat >"$deploy/packaging/web-watchdog.sh" <<'SH'
#!/usr/bin/env bash
if [[ "$CASE_MODE" == "delayed-start" ]]; then
  count_file="$CASE_DIR/watchdog-count"
  count=0
  [[ ! -f "$count_file" ]] || read -r count <"$count_file"
  count=$((count + 1))
  printf '%s\n' "$count" >"$count_file"
  (( count >= 25 ))
  exit
fi
exit 0
SH
  chmod +x "$deploy/packaging/web-watchdog.sh"
  cat >"$deploy/packaging/web-release.sh" <<'SH'
#!/usr/bin/env bash
verify() {
  local attempts="$1" delay="$2" attempt
  for ((attempt = 1; attempt <= attempts; attempt++)); do
    bash -c "$OVERDECK_WEB_RELEASE_VERIFY_CMD" && return 0
    (( attempt == attempts )) || sleep "$delay"
  done
  return 1
}

case "${1:-}" in
  promote) exit 0 ;;
  activate)
    release="$2"
    current="$(dirname "$release")/current"
    previous="$(dirname "$release")/previous"
    old=""
    old_previous=""
    [[ ! -L "$current" ]] || old="$(readlink "$current")"
    [[ ! -L "$previous" ]] || old_previous="$(readlink "$previous")"
    [[ -z "$old" ]] || ln -sfn "$old" "$previous"
    ln -sfn "$release" "$current"
    attempts="${OVERDECK_WEB_RELEASE_VERIFY_ATTEMPTS:-1}"
    delay="${OVERDECK_WEB_RELEASE_VERIFY_DELAY:-1}"
    bash -c "$OVERDECK_WEB_RELEASE_RESTART_CMD" && verify "$attempts" "$delay" && exit 0
    [[ -z "$old" ]] && rm -f "$current" || ln -sfn "$old" "$current"
    [[ -z "$old_previous" ]] && rm -f "$previous" || ln -sfn "$old_previous" "$previous"
    bash -c "$OVERDECK_WEB_RELEASE_RESTART_CMD" && verify "$attempts" "$delay" && exit 1
    exit 2
    ;;
  *) exit 2 ;;
esac
SH
  chmod +x "$deploy/packaging/web-release.sh"
  cat >"$deploy/packaging/web-preflight.sh" <<'SH'
#!/usr/bin/env bash
[[ "$CASE_MODE" != "preflight-fail" && "$CASE_MODE" != "queue-preserve" ]]
SH
  chmod +x "$deploy/packaging/web-preflight.sh"

  # The real parity probe reaches every buildbox over ssh; the fixture supplies its verdict.
  cat >"$deploy/modules/workstation/claude/bin/sandbox-provision" <<'SH'
#!/usr/bin/env bash
printf 'sandbox-parity:%s\n' "$*" >>"$INSTALL_LOG"
printf 'debian1 probed\n'
exit "${SANDBOX_PARITY_RC:-0}"
SH
  chmod +x "$deploy/modules/workstation/claude/bin/sandbox-provision"

  for installer in install-controller.sh install.sh install-botmaster-proxy.sh install-web.sh install-buildbox-parity.sh; do
    cat >"$caller/packaging/$installer" <<'SH'
#!/usr/bin/env bash
printf 'stale-caller:%s\n' "$0" >>"$INSTALL_LOG"
exit 91
SH
    cat >"$deploy/packaging/$installer" <<'SH'
#!/usr/bin/env bash
[[ -f "$CHECKOUT_MARKER" ]] || exit 92
printf 'deploy-clone:%s\n' "$0" >>"$INSTALL_LOG"
exit 0
SH
    chmod +x "$caller/packaging/$installer" "$deploy/packaging/$installer"
  done

  cat >"$bin/git" <<'SH'
#!/usr/bin/env bash
if [[ "${1:-}" == "status" ]]; then
  if [[ -f "$DEPLOY_ROOT/modules/workstation/claude/bin/untracked-tool" ]]; then
    printf '?? modules/workstation/claude/bin/untracked-tool\n'
  fi
  if grep -q 'foreign edit' "$DEPLOY_ROOT/modules/workstation/claude/buildbox-hosts.json" 2>/dev/null; then
    printf ' M modules/workstation/claude/buildbox-hosts.json\n'
  fi
  if [[ -d "$DEPLOY_ROOT/apps/web/.releases" ]] \
    && ! grep -qxF '/apps/web/.releases/' "$DEPLOY_ROOT/.git/info/exclude" 2>/dev/null; then
    printf '?? apps/web/.releases/current\n'
  fi
elif [[ "${1:-}" == "checkout" && "${2:-}" == "--quiet" && "${3:-}" == "--detach" && "${4:-}" == "origin/main" ]]; then
  touch "$CHECKOUT_MARKER"
elif [[ "${1:-}" == "rev-parse" ]]; then
  printf 'deadbeef\n'
elif [[ "${1:-}" == "cat-file" ]]; then
  exit 0
elif [[ "${1:-}" == "diff" ]]; then
  [[ "$CASE_MODE" != "web-changed" ]] || printf 'apps/web/src/pages/index.astro\n'
fi
exit 0
SH
  cat >"$bin/pnpm" <<'SH'
#!/usr/bin/env bash
if [[ " $* " == *" --filter web build "* ]]; then
  printf 'pnpm-build-invoked\n' >>"$INSTALL_LOG"
  mkdir -p "$DEPLOY_ROOT/apps/web/dist/server"
  touch "$DEPLOY_ROOT/apps/web/dist/server/entry.mjs"
elif [[ " $* " == *" --filter web deploy "* ]]; then
  printf 'pnpm-deploy-invoked\n' >>"$INSTALL_LOG"
  target="${!#}"
  mkdir -p "$target/node_modules/pkg"
  touch "$target/node_modules/pkg/runtime.js"
fi
exit 0
SH
  cat >"$bin/bun" <<'SH'
#!/usr/bin/env bash
[[ "${1:-}" == "scripts/brief-canary.ts" ]] || exit 2
exit 0
SH
  cat >"$bin/systemctl" <<'SH'
#!/usr/bin/env bash
printf '%s\n' "$*" >>"$SYSTEMCTL_LOG"
exit 0
SH
  # The notification gate lives at an absolute path this fixture cannot relocate, so the
  # refresh branch would otherwise reach real root on the machine running the test.
  cat >"$bin/deck-sudo" <<'SH'
#!/usr/bin/env bash
printf 'deck-sudo:%s\n' "$*" >>"$INSTALL_LOG"
exit 0
SH
  cat >"$bin/sleep" <<'SH'
#!/usr/bin/env bash
exit 0
SH
  cat >"$bin/curl" <<'SH'
#!/usr/bin/env bash
url="${!#}"
case "$url" in
  *:31337/*) printf '200'; exit 0 ;;
  *:31338/*)
    count_file="$CASE_DIR/collector-count"
    count=0
    [[ ! -f "$count_file" ]] || read -r count <"$count_file"
    count=$((count + 1))
    printf '%s\n' "$count" >"$count_file"
    case "${COLLECTOR_MODE:-}" in
      reachable) printf '401'; exit 0 ;;
      delayed-ready)
        (( count > 19 )) && { printf '401'; exit 0; }
        ;;
    esac
    printf '000'
    exit 7
    ;;
  *) exit 2 ;;
esac
SH
  chmod +x "$bin"/*

  /usr/bin/git -C "$deploy" init -q
  printf '/apps/web/dist/\n/apps/web/.releases/\n' >"$deploy/.git/info/exclude"
  /usr/bin/git -C "$deploy" config user.name Fixture
  /usr/bin/git -C "$deploy" config user.email fixture@example.invalid
  /usr/bin/git -C "$deploy" add -A
  /usr/bin/git -C "$deploy" commit -qm "fixture"
  /usr/bin/git -C "$deploy" update-ref refs/remotes/origin/main HEAD

  if [[ "${QUEUE_SEED:-}" == 1 ]]; then
    mkdir -p "$case_dir/deploy-queue"
    : >"$case_dir/deploy-queue/req-seeded"
  fi

  HOME="$case_dir/home" \
    PATH="$bin:$PATH" \
    OVERDECK_DEPLOY_DIR="$deploy" \
    OVERDECK_DEPLOY_QUEUE_DIR="$case_dir/deploy-queue" \
    DEPLOY_ROOT="$deploy" \
    CASE_DIR="$case_dir" \
    CASE_MODE="$mode" \
    COLLECTOR_MODE="$collector" \
    SANDBOX_PARITY_RC="${SANDBOX_PARITY_RC:-0}" \
    CHECKOUT_MARKER="$case_dir/checkout-complete" \
    INSTALL_LOG="$case_dir/install.log" \
    SYSTEMCTL_LOG="$case_dir/systemctl.log" \
    bash "$caller/packaging/deploy-local.sh" >"$case_dir/stdout" 2>"$case_dir/stderr"
}

if run_case reachable \
  && grep -q '"status":"deployed"' "$TMP/reachable/stdout" \
  && grep -q '"collector_http":"401"' "$TMP/reachable/stdout"; then
  ok "accepts an actual collector HTTP 401 response"
else
  bad "accepts an actual collector HTTP 401 response"
fi

if run_case delayed-start reachable \
  && grep -q '"status":"deployed"' "$TMP/delayed-start/stdout" \
  && [[ "$(<"$TMP/delayed-start/watchdog-count")" -eq 25 ]]; then
  ok "waits for the activated web release to become ready"
else
  bad "waits for the activated web release to become ready"
fi

if run_case delayed-collector delayed-ready \
  && grep -q '"status":"deployed"' "$TMP/delayed-collector/stdout" \
  && [[ "$(<"$TMP/delayed-collector/collector-count")" -eq 21 ]]; then
  ok "waits through measured collector cold start without real sleeps"
else
  bad "waits through measured collector cold start without real sleeps"
fi

if run_case release-state reachable \
  && grep -q '"status":"deployed"' "$TMP/release-state/stdout" \
  && grep -qxF '/apps/web/.releases/' "$TMP/release-state/deploy/.git/info/exclude"; then
  ok "accepts generated web release state without weakening the dirty-clone gate"
else
  bad "accepts generated web release state without weakening the dirty-clone gate"
fi

if run_case preflight-fail reachable; then
  bad "removes an immutable release rejected by preflight"
elif grep -q '"status":"web-preflight-failed"' "$TMP/preflight-fail/stderr" \
  && ! compgen -G "$TMP/preflight-fail/deploy/apps/web/.releases/.build-*" >/dev/null; then
  ok "removes an immutable release rejected by preflight"
else
  bad "removes an immutable release rejected by preflight"
fi

if SANDBOX_PARITY_RC=1 run_case sandboxdrift reachable; [[ $? -ne 0 ]] \
  && grep -q '"status":"sandbox-image-drift"' "$TMP/sandboxdrift/stderr" \
  && ! grep -q '"status":"deployed"' "$TMP/sandboxdrift/stdout"; then
  ok "refuses to report deployed while a buildbox serves an older sandbox image"
else
  bad "refuses to report deployed while a buildbox serves an older sandbox image"
fi

if SANDBOX_PARITY_RC=4 run_case sandboxunreachable reachable \
  && grep -q '"status":"deployed"' "$TMP/sandboxunreachable/stdout" \
  && grep -q 'debian1 probed' "$TMP/sandboxunreachable/stderr"; then
  ok "an unreachable buildbox is reported but does not block the deploy"
else
  bad "an unreachable buildbox is reported but does not block the deploy"
fi

if [[ "$(grep -c '^deploy-clone:' "$TMP/reachable/install.log")" -eq 6 ]] \
  && ! grep -q '^stale-caller:' "$TMP/reachable/install.log"; then
  ok "installs all service and command artifacts from the deploy clone, not the stale caller tree"
else
  bad "installs all service and command artifacts from the deploy clone, not the stale caller tree"
fi

if [[ -f "$TMP/reachable/home/.config/systemd/user/agent.slice" ]] \
  && grep -qx 'CPUQuota=150%' "$TMP/reachable/home/.config/systemd/user/agent.slice" \
  && grep -qx 'CPUWeight=1' "$TMP/reachable/home/.config/systemd/user/agent.slice" \
  && grep -qx -- '--user daemon-reload' "$TMP/reachable/systemctl.log"; then
  ok "installs and reloads the agent CPU ceiling without restarting owner scopes"
else
  bad "installs and reloads the agent CPU ceiling without restarting owner scopes"
fi

if ! grep -qE 'harness-(run|queue|reconcile|watchdog)' "$TMP/reachable/systemctl.log" \
  && [[ ! -e "$TMP/reachable/home/.config/systemd/user/harness-run@.service" ]]; then
  ok "does not install or enable harness coordinator units"
else
  bad "does not install or enable harness coordinator units"
fi

if [[ "$(grep -Ec '^bash "\$\{DEPLOY\}/packaging/install-(controller|botmaster-proxy|web|buildbox-parity)\.sh"|^bash "\$\{DEPLOY\}/packaging/install\.sh"' "$SCRIPT")" -eq 5 ]]; then
  ok "all installer commands reference the deploy clone directly"
else
  bad "all installer commands reference the deploy clone directly"
fi

dry_run="$(OVERDECK_DEPLOY_DRY_RUN=1 OVERDECK_DEPLOY_DIR=/tmp/overdeck-deploy-fixture bash "$SCRIPT")"
if [[ "$dry_run" == $'install-gptbridge-links:/tmp/overdeck-deploy-fixture/modules/gptbridge/install.sh --links-only\nsync-pi-provider:/tmp/overdeck-deploy-fixture/modules/workstation/pi/agent/models.json\ninstall-user-bin:/tmp/overdeck-deploy-fixture/bin/deckctl sync apply bin\ninstall-workstation-bin:/tmp/overdeck-deploy-fixture/bin/deckctl sync apply claude bin\ninstall-workstation-lib:/tmp/overdeck-deploy-fixture/bin/deckctl sync apply claude lib\ninstall-cloudflare-token-registry:/tmp/overdeck-deploy-fixture/bin/deckctl sync apply claude cloudflare-token-targets.json\ninstall-buildbox-registry:/tmp/overdeck-deploy-fixture/bin/deckctl sync apply claude buildbox-hosts.json\ninstall-agent-slice:/tmp/overdeck-deploy-fixture/modules/monitor/systemd/user/agent.slice → $HOME/.config/systemd/user/agent.slice; systemctl --user daemon-reload\ninstall-deploy-queue:/tmp/overdeck-deploy-fixture/packaging/overdeck-deploy.{path,service} → $HOME/.config/systemd/user/; systemctl --user enable --now overdeck-deploy.path\ninstall-systray-commands:python3 /tmp/overdeck-deploy-fixture/modules/systray/install.py\ninstall-controller:/tmp/overdeck-deploy-fixture/packaging/install-controller.sh\ninstall-web:/tmp/overdeck-deploy-fixture/packaging/install-web.sh\ninstall-buildbox-parity:/tmp/overdeck-deploy-fixture/packaging/install-buildbox-parity.sh\nbrief-canary:/tmp/overdeck-deploy-fixture/collector/scripts/brief-canary.ts\nsandbox-image-parity:/tmp/overdeck-deploy-fixture/modules/workstation/claude/bin/sandbox-provision --check --all\nrestart:overdeck-collector.service overdeck-web.service overdeck-controller.service botmaster-proxy.service overdeck-web-watchdog.service' ]]; then
  ok "dry run reports the complete install and restart order"
else
  bad "dry run reports the complete install and restart order"
fi

if [[ -L "$TMP/reachable/home/.claude/bin" ]] \
  && [[ ! -e "$TMP/reachable/home/.claude/settings.json" ]] \
  && [[ ! -e "$TMP/reachable/home/.claude/skills" ]]; then
  ok "installs no plan launcher on PATH — the factory is the only executor"
else
  bad "installs no plan launcher on PATH — the factory is the only executor"
fi

if [[ -L "$TMP/reachable/home/.claude/lib" ]] \
  && [[ "$(readlink "$TMP/reachable/home/.claude/lib")" == "$TMP/reachable/deploy/modules/workstation/claude/lib" ]] \
  && [[ -L "$TMP/reachable/home/.claude/cloudflare-token-targets.json" ]] \
  && [[ "$(readlink "$TMP/reachable/home/.claude/cloudflare-token-targets.json")" == "$TMP/reachable/deploy/modules/workstation/claude/cloudflare-token-targets.json" ]]; then
  ok "installs token registry runtime files from the deploy clone"
else
  bad "installs token registry runtime files from the deploy clone"
fi

if [[ -L "$TMP/reachable/home/.claude/buildbox-hosts.json" ]] \
  && [[ "$(readlink "$TMP/reachable/home/.claude/buildbox-hosts.json")" == "$TMP/reachable/deploy/modules/workstation/claude/buildbox-hosts.json" ]]; then
  ok "installs the buildbox registry from the deploy clone"
else
  bad "installs the buildbox registry from the deploy clone"
fi

if run_case untracked; then
  bad "rejects untracked binaries before workstation install"
elif grep -q '"status":"deploy-clone-dirty"' "$TMP/untracked/stderr" \
  && [[ ! -e "$TMP/untracked/home/.claude/bin" ]]; then
  ok "rejects untracked binaries before workstation install"
else
  bad "rejects untracked binaries with deploy-clone-dirty status"
fi

if run_case modified; then
  bad "rejects a modified tracked file and names it"
elif grep -q '"status":"deploy-clone-dirty"' "$TMP/modified/stderr" \
  && grep -q 'M modules/workstation/claude/buildbox-hosts.json' "$TMP/modified/stderr" \
  && [[ ! -e "$TMP/modified/home/.claude/bin" ]]; then
  ok "rejects a modified tracked file and names it"
else
  bad "rejects a modified tracked file and names it"
fi

if run_case never-ready; then
  bad "rejects a collector that never becomes ready within the smoke budget"
elif grep -q '"status":"smoke-failed-rolled-back"' "$TMP/never-ready/stderr" \
  && [[ "$(<"$TMP/never-ready/collector-count")" -eq 120 ]] \
  && [[ "$(grep -cx -- '--user restart overdeck-collector.service overdeck-web.service overdeck-controller.service botmaster-proxy.service overdeck-web-watchdog.service' "$TMP/never-ready/systemctl.log")" -eq 2 ]] \
  && [[ "$(readlink "$TMP/never-ready/deploy/apps/web/.releases/current")" == "bootstrap-fixture" ]]; then
  ok "rolls back the prior release and reruns readiness when smoke never becomes ready"
else
  bad "rolls back the prior release and reruns readiness when smoke never becomes ready"
fi

lock="$TMP/deploy.lock"
queue="$TMP/deploy-queue"
lock_run() {
  OVERDECK_DEPLOY_DIR="$TMP/absent-clone" OVERDECK_DEPLOY_LOCK="$lock" \
    OVERDECK_DEPLOY_QUEUE_DIR="$queue" \
    OVERDECK_DEPLOY_LOCK_WAIT="$1" bash "$SCRIPT" 2>&1
}

if lock_run 1 | grep -q '"status":"no-deploy-clone"'; then
  ok "an uncontended deploy takes the lock and proceeds"
else
  bad "an uncontended deploy takes the lock and proceeds"
fi

flock "$lock" -c 'sleep 6' &
holder=$!
sleep 1
if lock_run 2 | grep -q '"status":"deploy-lock-timeout"'; then
  ok "a deploy that cannot take the lock fails loudly instead of racing the holder"
else
  bad "a deploy that cannot take the lock fails loudly instead of racing the holder"
fi
if compgen -G "$queue/req-*" >/dev/null; then
  ok "a timed-out request persists in the queue for the next drainer"
else
  bad "a timed-out request persists in the queue for the next drainer"
fi
rm -f "$queue"/req-*
if lock_run 30 | grep -q '"status":"no-deploy-clone"'; then
  ok "a deploy waits for the holder and then runs, rather than being skipped"
else
  bad "a deploy waits for the holder and then runs, rather than being skipped"
fi
if compgen -G "$queue/req-*" >/dev/null; then
  ok "a requester that becomes the holder leaves its failed run's request queued"
else
  bad "a requester that becomes the holder leaves its failed run's request queued"
fi
rm -f "$queue"/req-*
wait "$holder"

flock "$lock" -c 'sleep 30' &
holder=$!
sleep 1
lock_run 30 >"$TMP/coalesced.out" 2>&1 &
requester=$!
for _ in $(seq 50); do
  compgen -G "$queue/req-*" >/dev/null && break
  sleep 0.1
done
rm -f "$queue"/req-*
if wait "$requester" && grep -q '"status":"deployed-coalesced"' "$TMP/coalesced.out"; then
  ok "a queued request exits 0 once a successful deploy drains it"
else
  bad "a queued request exits 0 once a successful deploy drains it"
fi
kill "$holder" 2>/dev/null
wait "$holder" 2>/dev/null

if QUEUE_SEED=1 run_case queue-drain reachable \
  && grep -q '"status":"deployed"' "$TMP/queue-drain/stdout" \
  && [[ ! -e "$TMP/queue-drain/deploy-queue/req-seeded" ]]; then
  ok "a successful deploy drains requests queued before it started"
else
  bad "a successful deploy drains requests queued before it started"
fi

if QUEUE_SEED=1 run_case queue-preserve; then
  bad "a failed deploy never consumes queued requests"
elif grep -q '"status":"web-preflight-failed"' "$TMP/queue-preserve/stderr" \
  && [[ -e "$TMP/queue-preserve/deploy-queue/req-seeded" ]]; then
  ok "a failed deploy never consumes queued requests"
else
  bad "a failed deploy never consumes queued requests"
fi

if [[ -f "$TMP/queue-drain/home/.config/systemd/user/overdeck-deploy.path" ]] \
  && [[ -f "$TMP/queue-drain/home/.config/systemd/user/overdeck-deploy.service" ]] \
  && grep -q '^DirectoryNotEmpty=%h/.local/share/overdeck/deploy-queue$' \
    "$TMP/queue-drain/home/.config/systemd/user/overdeck-deploy.path" \
  && grep -q '^TimeoutStartSec=0$' "$TMP/queue-drain/home/.config/systemd/user/overdeck-deploy.service" \
  && grep -q '^StartLimitIntervalSec=15min$' "$TMP/queue-drain/home/.config/systemd/user/overdeck-deploy.service" \
  && grep -q '^StartLimitBurst=3$' "$TMP/queue-drain/home/.config/systemd/user/overdeck-deploy.service" \
  && grep -q '^ExecStart=%h/.local/share/overdeck/deploy/packaging/deploy-local.sh$' \
    "$TMP/queue-drain/home/.config/systemd/user/overdeck-deploy.service" \
  && grep -qx -- '--user enable --now overdeck-deploy.path' "$TMP/queue-drain/systemctl.log"; then
  ok "installs and enables the systemd queue drain units"
else
  bad "installs and enables the systemd queue drain units"
fi

if run_case web-unchanged reachable \
  && grep -q '"status":"deployed"' "$TMP/web-unchanged/stdout" \
  && ! grep -qx 'pnpm-build-invoked' "$TMP/web-unchanged/install.log" \
  && ! grep -qx 'pnpm-deploy-invoked' "$TMP/web-unchanged/install.log" \
  && [[ "$(readlink -f "$TMP/web-unchanged/deploy/apps/web/.releases/current")" \
        == "$TMP/web-unchanged/deploy/apps/web/.releases/.build-deadbeef-AAAAAA" ]]; then
  ok "skips the web build and reuses the current release when nothing web-relevant changed"
else
  bad "skips the web build and reuses the current release when nothing web-relevant changed"
fi

if run_case web-changed reachable \
  && grep -q '"status":"deployed"' "$TMP/web-changed/stdout" \
  && grep -qx 'pnpm-build-invoked' "$TMP/web-changed/install.log" \
  && grep -qx 'pnpm-deploy-invoked' "$TMP/web-changed/install.log"; then
  ok "still rebuilds when web-relevant files changed since the last release"
else
  bad "still rebuilds when web-relevant files changed since the last release"
fi

if run_case web-unchanged-dangling reachable \
  && grep -q '"status":"deployed"' "$TMP/web-unchanged-dangling/stdout" \
  && grep -qx 'pnpm-build-invoked' "$TMP/web-unchanged-dangling/install.log" \
  && grep -qx 'pnpm-deploy-invoked' "$TMP/web-unchanged-dangling/install.log"; then
  ok "rebuilds instead of skipping when current points at a pruned/missing release"
else
  bad "rebuilds instead of skipping when current points at a pruned/missing release"
fi

printf 'PASS=%s FAIL=%s\n' "$PASS" "$FAIL"
[[ "$FAIL" -eq 0 ]]
