#!/usr/bin/env bash
# Verify an activated immutable backend by typed health and exact revision identity.
set -euo pipefail

usage() {
  printf 'usage: %s <collector|controller|botmaster-proxy|actions-gateway> <url> <token-file|-> <component> <sha>\n' "$0" >&2
  exit 64
}

(($# == 5)) || usage
kind=$1
url=$2
token_file=$3
component=$4
sha=$5
TIMEOUT=${OVERDECK_BACKEND_READINESS_TIMEOUT:-180}
DELAY=${OVERDECK_BACKEND_READINESS_DELAY:-1}
CURL_TIMEOUT=${OVERDECK_BACKEND_READINESS_CURL_TIMEOUT:-5}

[[ "$kind" == "$component" && "$component" =~ ^(collector|controller|botmaster-proxy|actions-gateway)$ ]] || usage
[[ "$sha" =~ ^[0-9a-f]{40}$ ]] || { printf 'backend-readiness: invalid full sha\n' >&2; exit 64; }
[[ "$TIMEOUT" =~ ^[0-9]+$ && "$DELAY" =~ ^[0-9]+([.][0-9]+)?$ ]] \
  || { printf 'backend-readiness: invalid retry timing\n' >&2; exit 64; }

work_root="${XDG_CACHE_HOME:-$HOME/.cache}/overdeck/readiness"
mkdir -p "$work_root"
work=$(mktemp -d "$work_root/backend.XXXXXX") || exit 2
trap 'rm -rf "$work"' EXIT
body="$work/body.json"
curl_auth=()
if [[ "$component" == collector || "$component" == controller ]]; then
  [[ -f "$token_file" && ! -L "$token_file" && -r "$token_file" ]] \
    || { printf 'backend-readiness: %s token unavailable\n' "$component" >&2; exit 65; }
  token=$(<"$token_file")
  [[ -n "$token" && "$token" != *$'\n'* && "$token" != *$'\r'* ]] \
    || { printf 'backend-readiness: %s token is malformed\n' "$component" >&2; exit 65; }
  header="$work/auth.header"
  printf 'Authorization: Bearer %s' "$token" >"$header"
  chmod 0600 "$header"
  curl_auth=(--header "@$header")
else
  [[ "$token_file" == - ]] || usage
fi

attempt=0
start=$SECONDS
while :; do
  attempt=$((attempt + 1))
  code=000
  code=$(curl --silent --show-error --output "$body" --write-out '%{http_code}' \
    --connect-timeout "$CURL_TIMEOUT" --max-time "$CURL_TIMEOUT" --max-filesize 1048576 \
    "${curl_auth[@]}" --url "$url" 2>"$work/curl.error") || true
  if [[ "$code" == 200 ]] && python3 - "$body" "$sha" <<'PY'
import json
import sys

path, expected_sha = sys.argv[1:]
try:
    with open(path, "rb") as stream:
        value = json.load(stream)
except (OSError, ValueError):
    raise SystemExit(1)
good = (
    isinstance(value, dict)
    and value.get("ok") is True
    and value.get("deployedSha") == expected_sha
)
raise SystemExit(0 if good else 1)
PY
  then
    printf 'backend-readiness: %s ready at %s after %d attempt(s)\n' "$component" "$sha" "$attempt"
    exit 0
  fi
  (( SECONDS - start < TIMEOUT )) || break
  sleep "$DELAY"
done

printf 'backend-readiness: %s did not serve expected sha %s after %d attempt(s) (last_http=%s)\n' \
  "$component" "$sha" "$attempt" "$code" >&2
exit 1
