#!/bin/sh
# Download one immutable artifact; stdout is its verified absolute path.
set -eu
umask 077
: "${API_BASE:?set API_BASE to the HTTPS API origin, without a trailing slash}"
: "${TOKEN:?set TOKEN to an RS256 download token}"
: "${DATABASE:?set DATABASE to the published database name}"
case "$API_BASE" in https://*) ;; *) echo 'HTTPS API_BASE required' >&2; exit 1;; esac
case "$DATABASE" in ''|*[!A-Za-z0-9_.-]*|.|..) echo 'Invalid database name' >&2; exit 1;; esac
mkdir -p "${OUT_DIR:-.dev-data}/$DATABASE"
root=$(cd "${OUT_DIR:-.dev-data}/$DATABASE" && pwd)
manifest=$(mktemp "$root/manifest.XXXXXX")
trap 'rm -f "$manifest"' 0 HUP INT TERM
status=$(curl -sS --fail -H "Authorization: Bearer $TOKEN" \
  -w '%{http_code}' -o "$manifest" "$API_BASE/databases/$DATABASE/latest")
[ "$status" = 200 ] || { echo "Latest artifact not ready: HTTP $status" >&2; exit 1; }
id=$(jq -er '.id | strings' "$manifest")
case "$id" in ''|*[!A-Za-z0-9_.-]*|.|..) echo 'Invalid artifact id' >&2; exit 1;; esac
expected=$(jq -er '.sha256 | select(test("^[0-9a-f]{64}$"))' "$manifest")
size=$(jq -er '.size_bytes | select(type == "number" and . >= 0 and floor == .)' "$manifest")
mkdir -p "$root/$id"
target="$root/$id/artifact.tar"
cp "$manifest" "$root/$id/manifest.json"
verify() {
  [ -f "$target" ] && [ "$(wc -c < "$target" | tr -d ' ')" = "$size" ] &&
    printf '%s  %s\n' "$expected" "$target" | sha256sum -c - >&2
}
if ! verify; then
  # --fail keeps an HTTP error body out of the artifact. A 416 is not success.
  curl --fail --silent --show-error -C - -H "Authorization: Bearer $TOKEN" \
    -o "$target" "$API_BASE/databases/$DATABASE/artifacts/$id/download"
  verify || { echo 'Verification failed; do not restore' >&2; exit 1; }
fi
jq '{id, engine, format, capture_time, replication_position, engine_min_version, restore_notes}' "$manifest" >&2
printf '%s\n' "$target"
