#!/bin/bash
# Refresh the CPU worker's copy of the compact serving index from the R2
# mirror (catalog/current.json -> immutable catalog/serving-index-<sha256>).
# Verified by sha256 and replaced atomically; the seats read it on every
# on-demand materialization, so a half-written file is never visible.
set -euo pipefail
BASE=${W3CS_CATALOG_BASE_URL:-https://cdn.war3replays.com}
TARGET=${W3CS_CATALOG_INDEX:-/home/ubuntu/w3cs-lab/catalog-serving.json}
OWNER=${W3CS_SERVICE_USER:-ubuntu}
MARKER="$TARGET.sha256"
# current.json is the one mutable pointer. The CDN caches by full URL, so a
# unique query string always reaches R2 instead of an edge copy (the edge
# applies its own browser TTL regardless of the object's Cache-Control).
current=$(curl -fsS --max-time 20 "$BASE/catalog/current.json?t=$(date +%s)")
sha256=$(python3 -c 'import json,sys; d=json.load(sys.stdin); print(d["sha256"])' <<<"$current")
key=$(python3 -c 'import json,sys; d=json.load(sys.stdin); print(d["key"])' <<<"$current")
[[ "$sha256" =~ ^[0-9a-f]{64}$ && "$key" == catalog/serving-index-$sha256.json ]] || {
  echo "catalog/current.json is malformed" >&2; exit 1; }
if [ -f "$MARKER" ] && [ "$(cat "$MARKER")" = "$sha256" ] && [ -s "$TARGET" ]; then
  exit 0
fi
tmp=$(mktemp "$(dirname "$TARGET")/.catalog-serving.XXXXXX")
trap 'rm -f "$tmp"' EXIT
curl -fsS --max-time 120 -o "$tmp" "$BASE/$key"
actual=$(sha256sum "$tmp" | cut -d' ' -f1)
[ "$actual" = "$sha256" ] || { echo "serving index sha256 mismatch" >&2; exit 1; }
python3 -c 'import json,sys; d=json.load(open(sys.argv[1])); assert d.get("schema")==3 and d["replays"]' "$tmp"
chmod 0644 "$tmp"
chown "$OWNER:$OWNER" "$tmp"
mv -f "$tmp" "$TARGET"
trap - EXIT
echo "$sha256" > "$MARKER"
echo "serving index updated: $sha256 ($(python3 -c 'import json,sys; print(json.load(sys.stdin)["replays"])' <<<"$current") replays)"

# A replay's descriptor (replays/<sha1>.json) is written on its first
# materialization and read by every later session. When a new index routes
# that replay elsewhere (another engine profile - the 1.24a/b re-route of
# the 2009 events left descriptors saying native-124cde - or new played/map
# bytes), rewrite it from the new index; bytes come from the sha1 cache, so
# this is a few JSON rewrites. Best effort: a failure here must not undo
# the index swap above.
LAB=$(dirname "$TARGET")
REPLAY_ROOT=${W3CS_REPLAY_ROOT:-$LAB/replays}
if [ -f "$LAB/materialize-catalog-replay.py" ] && [ -d "$REPLAY_ROOT" ]; then
  refresh=(python3 "$LAB/materialize-catalog-replay.py" --index "$TARGET" \
    --output-root "$REPLAY_ROOT" --base-url "$BASE" --refresh-stale)
  if [ "$(id -un)" != "$OWNER" ]; then
    refresh=(runuser -u "$OWNER" -- "${refresh[@]}")
  fi
  "${refresh[@]}" || echo "WARN: stale descriptor refresh failed" >&2
fi
