#!/bin/sh
set -eu

# Extract name and version from package.json using jq
NAME=$(jq -r '.name' package.json)
VERSION=$(get-version)

# Resolve the base domain (and this worker's subdomain), then deploy onto the
# custom domain via `--domain`. This keeps the real domain out of versioned files
# — committed wrangler.jsonc has no routes, and the base domain is passed as the
# DOMAIN var at runtime.
#
# The domain comes from the RECFLARE_DOMAIN env var. For local dev that's set in a
# gitignored .env at the repo root; in CI it's an exported secret. An already-set
# RECFLARE_DOMAIN wins and skips the file. Per-app subdomain overrides come from
# RECFLARE_SUBDOMAINS (a JSON object, e.g. {"playersettings":"settings"}).
if [ -z "${RECFLARE_DOMAIN:-}" ]; then
	ENV_FILE="$(git rev-parse --show-toplevel)/.env"
	if [ -f "$ENV_FILE" ]; then
		set -a
		. "$ENV_FILE"
		set +a
	fi
fi

if [ -z "${RECFLARE_DOMAIN:-}" ]; then
	echo "error: RECFLARE_DOMAIN is not set — export it or add it to .env (see .env.example)" >&2
	exit 1
fi

DOMAIN="$RECFLARE_DOMAIN"
SUBDOMAINS_JSON=${RECFLARE_SUBDOMAINS:-}
[ -n "$SUBDOMAINS_JSON" ] || SUBDOMAINS_JSON='{}'

DIR=$(basename "$PWD")
# Per-app subdomain override, falling back to the worker's directory name.
SUBDOMAIN=$(printf '%s' "$SUBDOMAINS_JSON" | jq -r --arg d "$DIR" '.[$d] // $d')
HOST="$SUBDOMAIN.$DOMAIN"

# Splice deploy-time resource ids into a generated config. The committed
# wrangler.jsonc carries "local" placeholders so it needs no per-developer edits;
# the real ids stay in the gitignored .env / CI secrets. Workers without these
# bindings simply have no placeholder to replace.
#
#   D1 — RECFLARE_D1: a single id (all workers share the one `recflare` database).
#   KV — RECFLARE_KV: a JSON object keyed by binding name, since each KV namespace
#        is distinct, e.g. {"RECFLARE_MATCH_PRESENCE":"…","RECFLARE_PLAYER_SETTINGS":"…"}.
#   Secrets Store — RECFLARE_SECRETS_STORE: a single store id (all workers bind the
#        one shared store for the JWT signing key).
CONFIG="wrangler.jsonc"

# Workers built with @cloudflare/vite-plugin (e.g. the React SPA in www) emit a
# deploy-ready config into dist/<dir>/ that carries the built worker
# (main: index.js), the resolved assets.directory, and no_bundle. The committed
# wrangler.jsonc leaves assets.directory out on purpose — the plugin fills it in —
# so deploying the source config fails with "assets ... missing the required
# directory property". Prefer the generated config when it exists. These workers
# have no D1/KV/Secrets bindings, so the id-splicing below is skipped.
VITE_CONFIG="dist/$DIR/wrangler.json"
if [ -f "$VITE_CONFIG" ]; then
	CONFIG="$VITE_CONFIG"
fi

NEEDS_D1=$(grep -q '"database_id": *"local"' wrangler.jsonc 2>/dev/null && echo 1 || true)
NEEDS_KV=$(grep -q '"id": *"local"' wrangler.jsonc 2>/dev/null && echo 1 || true)
NEEDS_STORE=$(grep -q '"store_id": *"local"' wrangler.jsonc 2>/dev/null && echo 1 || true)

if [ "$CONFIG" = "wrangler.jsonc" ] && { [ -n "$NEEDS_D1" ] || [ -n "$NEEDS_KV" ] || [ -n "$NEEDS_STORE" ]; }; then
	CONFIG="wrangler.generated.jsonc"
	# Generated alongside the original so its relative paths (main, migrations_dir)
	# still resolve. Gitignored; removed on exit so `wrangler dev` is unaffected.
	trap 'rm -f wrangler.generated.jsonc wrangler.generated.tmp' EXIT
	cp wrangler.jsonc wrangler.generated.jsonc

	if [ -n "$NEEDS_D1" ]; then
		DB_ID=${RECFLARE_D1:-}
		if [ -z "$DB_ID" ]; then
			echo "error: RECFLARE_D1 is not set — add the recflare D1 id to .env (see .env.example)" >&2
			exit 1
		fi
		sed -E 's/("database_id"[[:space:]]*:[[:space:]]*")[^"]*(")/\1'"$DB_ID"'\2/' \
			wrangler.generated.jsonc >wrangler.generated.tmp
		mv wrangler.generated.tmp wrangler.generated.jsonc
	fi

	if [ -n "$NEEDS_KV" ]; then
		KV_JSON=${RECFLARE_KV:-}
		[ -n "$KV_JSON" ] || KV_JSON='{}'
		# Map binding name -> id, then replace each kv_namespaces `"id": "local"`
		# with the id for its nearest preceding "binding" line. awk keeps state so
		# multiple namespaces in one file each get the right id.
		KV_PAIRS=$(printf '%s' "$KV_JSON" | jq -r 'to_entries[] | "\(.key)\t\(.value)"')
		awk -v pairs="$KV_PAIRS" '
			BEGIN {
				n = split(pairs, lines, "\n")
				for (i = 1; i <= n; i++) {
					if (lines[i] == "") continue
					t = index(lines[i], "\t")
					id[substr(lines[i], 1, t - 1)] = substr(lines[i], t + 1)
				}
			}
			/"binding"[[:space:]]*:/ {
				b = $0
				sub(/.*"binding"[[:space:]]*:[[:space:]]*"/, "", b)
				sub(/".*/, "", b)
				curbind = b
			}
			/"id"[[:space:]]*:[[:space:]]*"local"/ {
				if (!(curbind in id)) {
					print "error: no KV id for binding [" curbind "] in RECFLARE_KV — add it to .env (see .env.example)" >"/dev/stderr"
					exit 3
				}
				sub(/"local"/, "\"" id[curbind] "\"")
			}
			{ print }
		' wrangler.generated.jsonc >wrangler.generated.tmp || exit 1
		mv wrangler.generated.tmp wrangler.generated.jsonc
	fi

	if [ -n "$NEEDS_STORE" ]; then
		STORE_ID=${RECFLARE_SECRETS_STORE:-}
		if [ -z "$STORE_ID" ]; then
			echo "error: RECFLARE_SECRETS_STORE is not set — add the secrets store id to .env (see .env.example)" >&2
			exit 1
		fi
		sed -E 's/("store_id"[[:space:]]*:[[:space:]]*")[^"]*(")/\1'"$STORE_ID"'\2/' \
			wrangler.generated.jsonc >wrangler.generated.tmp
		mv wrangler.generated.tmp wrangler.generated.jsonc
	fi
fi

# Vite-built configs set no_bundle (vite already bundled and minified), which is
# incompatible with --minify. Only pass --minify when wrangler does the bundling.
MINIFY="--minify"
[ "$CONFIG" = "$VITE_CONFIG" ] && MINIFY=""

# Deploy with wrangler using the extracted values as binding variables
echo "Deploying worker $NAME version $VERSION to $HOST"
wrangler deploy \
	--config "$CONFIG" \
	--var NAME:"$NAME" \
	--var SENTRY_RELEASE:"$VERSION" \
	--var DOMAIN:"$DOMAIN" \
	--domain "$HOST" \
	$MINIFY \
	"$@"
