#!/usr/bin/env bash
#
# Publish a channel's Sparkle artifacts (the signed/notarized DMG[s] + the EdDSA-signed
# appcast) to the R2 bucket served at updates.nucleic.blakeslee.xyz. The appcast already
# carries the update signatures, so this is plain static hosting — a bucket object PUT.
#
# Object layout:
#   <channel>/<file>.dmg      DMGs, foldered by channel for tidy download links
#                             (e.g. beta/Nucleic-Beta-0.1.0.828.dmg)
#   appcast-<channel>.xml     Sparkle feed at the bucket root (build's baked-in SUFeedURL)
#   <channel>/latest          302 → newest DMG, served by the cloud/nucleic-updates Worker
#
#   scripts/upload-r2.sh {beta|rc|stable}
#
# Env:
#   NUCLEIC_R2_BUCKET   target R2 bucket (default: nucleic-updates)
#   NUCLEIC_FEED_BASE   feed host, used only in the printed verify URL
#                       (default: https://updates.nucleic.blakeslee.xyz)
#   WRANGLER            wrangler invocation (default: "npx --yes wrangler")
#
# Auth: wrangler must be logged in (`wrangler login`) or CLOUDFLARE_API_TOKEN set with R2 write.
set -euo pipefail

CHANNEL="${1:?usage: upload-r2.sh (beta|rc|stable)}"
case "$CHANNEL" in
  beta)   SLUG="Nucleic-Beta" ;;
  rc)     SLUG="Nucleic-RC" ;;
  stable) SLUG="Nucleic" ;;
  *) echo "usage: $0 {beta|rc|stable}" >&2; exit 2 ;;
esac

ROOT="$(cd "$(dirname "$0")/.." && pwd)"
BUCKET="${NUCLEIC_R2_BUCKET:-nucleic-updates}"
FEED_BASE="${NUCLEIC_FEED_BASE:-https://updates.nucleic.blakeslee.xyz}"
WRANGLER="${WRANGLER:-npx --yes wrangler}"

APPCAST="$ROOT/dist/appcast-$CHANNEL.xml"
[ -f "$APPCAST" ] || { echo "upload-r2: $APPCAST missing — run generate-appcast.sh $CHANNEL first" >&2; exit 1; }

shopt -s nullglob
dmgs=("$ROOT/dist/${SLUG}-"*.dmg)
shopt -u nullglob
[ "${#dmgs[@]}" -gt 0 ] || { echo "upload-r2: no ${SLUG}-*.dmg in dist/ — build a release first" >&2; exit 1; }

put() { # <local-file> <key> <content-type> <cache-control>
  echo "  ↑ $2"
  $WRANGLER r2 object put "$BUCKET/$2" --file "$1" \
    --content-type "$3" --cache-control "$4" --remote
}

echo "▸ Uploading $CHANNEL → r2://$BUCKET"
# DMGs go under the channel folder (key "<channel>/<file>.dmg") for tidy, predictable download
# links — updates.nucleic.blakeslee.xyz/<channel>/<file>.dmg — matching the enclosure URLs
# generate-appcast.sh wrote (--download-url-prefix "$FEED_BASE/$CHANNEL/"). They're
# content-addressed by version → cache forever.
for dmg in "${dmgs[@]}"; do
  put "$dmg" "$CHANNEL/$(basename "$dmg")" "application/octet-stream" "public, max-age=31536000, immutable"
done
# The appcast (the Sparkle feed) stays at the bucket root, where each build's baked-in SUFeedURL
# points it. It changes each release → short cache so updates surface quickly.
put "$APPCAST" "appcast-$CHANNEL.xml" "application/xml" "public, max-age=300"

echo "✓ Uploaded $CHANNEL to r2://$BUCKET"
echo "  Verify: curl -I $FEED_BASE/appcast-$CHANNEL.xml"
echo "          curl -I $FEED_BASE/$CHANNEL/$(basename "${dmgs[0]}")"
echo "          curl -I $FEED_BASE/$CHANNEL/latest   # → 302 to the newest DMG"
