#!/usr/bin/env bash
set -uo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SCRIPT="$ROOT/backend-readiness.sh"
TESTROOT="${XDG_CACHE_HOME:-$HOME/.cache}/overdeck/tests/backend-readiness/run-$$-$RANDOM"
BIN="$TESTROOT/bin"
TOKEN_FILE="$TESTROOT/token"
CURL_LOG="$TESTROOT/curl.log"
mkdir -p "$BIN"
trap 'rm -rf "$TESTROOT"' EXIT
printf 'fixture-token\n' >"$TOKEN_FILE"

fails=0
check() {
  if (( $1 == 0 )); then printf 'ok - %s\n' "$2"
  else printf 'FAIL - %s\n' "$2"; fails=$((fails + 1)); fi
}

cat >"$BIN/curl" <<'SH'
#!/usr/bin/env bash
printf '%s\n' "$*" >>"$CURL_LOG"
body=""
header_arg=""
while (($#)); do
  case "$1" in
    --output) body=$2; shift 2 ;;
    --header) header_arg=$2; shift 2 ;;
    *) shift ;;
  esac
done
[[ -z "$header_arg" || "$header_arg" == @* ]] || exit 91
if [[ -n "$header_arg" ]]; then
  header_file=${header_arg#@}
  [[ "$(<"$header_file")" == 'Authorization: Bearer fixture-token' ]] || exit 92
fi
case "${CURL_MODE:-good}" in
  good) printf '{"ok":true,"deployedSha":"%s"}\n' "$EXPECTED_SHA" >"$body"; printf 200 ;;
  wrong-sha) printf '{"ok":true,"deployedSha":"%s"}\n' "$OTHER_SHA" >"$body"; printf 200 ;;
  wrong-type) printf '[]\n' >"$body"; printf 200 ;;
  unavailable) printf 503 ;;
esac
SH
cat >"$BIN/node" <<'SH'
#!/usr/bin/env bash
printf '%s\n' "$*" >"$NODE_LOG"
SH
chmod +x "$BIN/curl" "$BIN/node" "$SCRIPT"

SHA=$(printf 'a%.0s' {1..40})
OTHER_SHA=$(printf 'b%.0s' {1..40})
run_readiness() {
  local component=${1:-collector} url token_file="$TOKEN_FILE"
  case "$component" in
    collector) url=http://127.0.0.1:31341/health ;;
    controller) url=http://127.0.0.1:8787/health ;;
    botmaster-proxy) url=http://127.0.0.1:31340/health; token_file=- ;;
    actions-gateway) url=http://127.0.0.1:31401/health; token_file=- ;;
  esac
  CURL_LOG="$CURL_LOG" CURL_MODE="${CURL_MODE:-good}" EXPECTED_SHA="$SHA" OTHER_SHA="$OTHER_SHA" \
    XDG_CACHE_HOME="$TESTROOT/cache" OVERDECK_BACKEND_READINESS_TIMEOUT=0 \
    PATH="$BIN:$PATH" bash "$SCRIPT" "$component" "$url" "$token_file" "$component" "$SHA"
}

output=$(run_readiness 2>&1)
if [[ "$output" == "backend-readiness: collector ready at $SHA after 1 attempt(s)" ]] \
  && ! grep -q 'fixture-token' "$CURL_LOG"; then rc=0; else rc=1; fi
check "$rc" 'typed collector health accepts the exact revision without putting the token in argv'

output=$(run_readiness controller 2>&1)
if [[ "$output" == "backend-readiness: controller ready at $SHA after 1 attempt(s)" ]]; then rc=0; else rc=1; fi
check "$rc" 'typed controller health accepts the exact revision'

for component in botmaster-proxy actions-gateway; do
  : >"$CURL_LOG"
  output=$(run_readiness "$component" 2>&1)
  if [[ "$output" == "backend-readiness: $component ready at $SHA after 1 attempt(s)" ]] \
    && ! grep -q -- '--header' "$CURL_LOG"; then rc=0; else rc=1; fi
  check "$rc" "typed $component health accepts the exact revision without an auth header"
done

GATEWAY_CONFIG="$TESTROOT/gateway.env"
NODE_LOG="$TESTROOT/node.log"
printf 'fixture=true\n' >"$GATEWAY_CONFIG"
combined=$(CURL_LOG="$CURL_LOG" NODE_LOG="$NODE_LOG" EXPECTED_SHA="$SHA" OTHER_SHA="$OTHER_SHA" \
  XDG_CACHE_HOME="$TESTROOT/cache" OVERDECK_BACKEND_READINESS_TIMEOUT=0 PATH="$BIN:$PATH" \
  bash "$ROOT/actions-gateway-readiness.sh" http://127.0.0.1:31401 "$GATEWAY_CONFIG" "$BIN/node" actions-gateway "$SHA" 2>&1)
if [[ "$combined" == *"backend-readiness: actions-gateway ready at $SHA after 1 attempt(s)"* ]] \
  && [[ "$(<"$NODE_LOG")" == "$ROOT/test-actions-gateway-r0.mjs --endpoint http://127.0.0.1:31401 --config $GATEWAY_CONFIG" ]]; then rc=0; else rc=1; fi
check "$rc" 'Actions Gateway rollback boundary includes exact health and authenticated smoke through the selected Node runtime'

CURL_MODE=wrong-sha run_readiness >/dev/null 2>&1
if [[ "$?" != 0 ]]; then rc=0; else rc=1; fi
check "$rc" 'wrong revision identity is rejected'

CURL_MODE=wrong-type run_readiness >/dev/null 2>&1
if [[ "$?" != 0 ]]; then rc=0; else rc=1; fi
check "$rc" 'wrong JSON shape is rejected'

CURL_MODE=unavailable run_readiness >/dev/null 2>&1
if [[ "$?" != 0 ]]; then rc=0; else rc=1; fi
check "$rc" 'non-200 health is rejected'

BAD_TOKEN="$TESTROOT/bad-token"
printf 'bad\ntoken\n' >"$BAD_TOKEN"
XDG_CACHE_HOME="$TESTROOT/cache" OVERDECK_BACKEND_READINESS_TIMEOUT=0 PATH="$BIN:$PATH" \
  bash "$SCRIPT" collector http://127.0.0.1:31341/health "$BAD_TOKEN" collector "$SHA" >/dev/null 2>&1
if [[ "$?" != 0 ]]; then rc=0; else rc=1; fi
check "$rc" 'a token containing a header break is refused before curl'

PATH="$BIN:$PATH" bash "$SCRIPT" collector http://127.0.0.1:31341/health "$TOKEN_FILE" collector short >/dev/null 2>&1
if [[ "$?" == 64 ]]; then rc=0; else rc=1; fi
check "$rc" 'malformed deployment revision is a usage failure'

(( fails == 0 )) || { printf '%s check(s) failed\n' "$fails" >&2; exit 1; }
printf 'backend-readiness: all checks passed\n'
