#!/usr/bin/env bash
# Refresh the local Payload seed snapshot from staging, then force-apply it to
# the local development Payload database. Normal db:up never calls staging.
set -euo pipefail

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd -- "$SCRIPT_DIR/../.." && pwd)"
COMPOSE_FILE="$ROOT_DIR/docker/compose.local.yml"
SNAPSHOT="$ROOT_DIR/.local/payload-staging.dump"
STAGING_ENV=""
DEV_ENV=""
SOURCE_PG_ENV=""
ASSUME_YES=false
[ "${1:-}" = "--yes" ] && ASSUME_YES=true

info() { printf '▶ %s\n' "$*"; }
die() { printf 'Error: %s\n' "$*" >&2; exit 1; }

if command -v docker >/dev/null 2>&1; then RUNTIME=docker
elif command -v podman >/dev/null 2>&1; then RUNTIME=podman
else die "Docker or Podman is required."; fi
"$RUNTIME" info >/dev/null 2>&1 || die "$RUNTIME is not usable."

mkdir -p "$ROOT_DIR/.local"
chmod 700 "$ROOT_DIR/.local"
cleanup() {
  [ -z "$STAGING_ENV" ] || rm -f "$STAGING_ENV"
  [ -z "$DEV_ENV" ] || rm -f "$DEV_ENV"
  [ -z "$SOURCE_PG_ENV" ] || rm -f "$SOURCE_PG_ENV"
  rm -f "${SNAPSHOT}.tmp"
}
trap cleanup EXIT INT TERM HUP

STAGING_ENV="$(mktemp "${TMPDIR:-/tmp}/convex-monorepo-staging.XXXXXX.env")"
DEV_ENV="$(mktemp "${TMPDIR:-/tmp}/convex-monorepo-dev.XXXXXX.env")"
sh "$ROOT_DIR/scripts/export-env" staging > "$STAGING_ENV"
sh "$ROOT_DIR/scripts/export-env" dev > "$DEV_ENV"

validate_url() {
  local env_file="$1" expected="$2"
  bunx dotenv -e "$env_file" -- node -e '
    const expected = process.argv[1];
    const raw = process.env.PAYLOAD_DB_URL;
    if (!raw) process.exit(2);
    const url = new URL(raw);
    const local = url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "::1";
    if ((expected === "local") !== local) process.exit(3);
  ' "$expected" || die "PAYLOAD_DB_URL safety check failed for the $expected environment."
}

validate_url "$STAGING_ENV" remote
validate_url "$DEV_ENV" local

next_is_running=false
if command -v ss >/dev/null 2>&1; then
  ss -ltnH 'sport = :3000' | grep -q . && next_is_running=true
elif command -v lsof >/dev/null 2>&1; then
  lsof -nP -iTCP:3000 -sTCP:LISTEN >/dev/null 2>&1 && next_is_running=true
elif curl -sS --max-time 1 http://localhost:3000 >/dev/null 2>&1; then
  next_is_running=true
fi
if [ "$next_is_running" = true ]; then
  die "Next is running on port 3000. Stop bun dev:next before replacing Payload data."
fi

SOURCE_PG_ENV="$(mktemp "${TMPDIR:-/tmp}/convex-monorepo-pg.XXXXXX.env")"
PG_ENV_FILE="$SOURCE_PG_ENV" bunx dotenv -e "$STAGING_ENV" -- sh -c '
  umask 077
  printf "PGDATABASE=%s\n" "$PAYLOAD_DB_URL" > "$PG_ENV_FILE"
'

if [ "$ASSUME_YES" != true ]; then
  printf 'This will download staging Payload data and replace the LOCAL Payload database.\n'
  printf 'The snapshot may contain user records and password hashes; it stays under .local/.\n'
  read -r -p 'Continue? [y/N] ' answer
  case "$answer" in y|Y|yes|YES) ;; *) echo "Cancelled."; exit 0 ;; esac
fi

info "Exporting a read-only snapshot from staging Payload Postgres"
"$RUNTIME" run --rm --network host --env-file "$SOURCE_PG_ENV" \
  docker.io/library/postgres:17 \
  sh -c 'exec pg_dump --dbname="$PGDATABASE" --format=custom --no-owner --no-acl' \
  > "${SNAPSHOT}.tmp"
mv "${SNAPSHOT}.tmp" "$SNAPSHOT"
chmod 600 "$SNAPSHOT"

info "Ensuring local Payload Postgres is running"
bash "$ROOT_DIR/scripts/db/seed-payload" --force --yes

printf '\nLocal Payload seed snapshot refreshed and applied.\n'
printf 'Snapshot: .local/payload-staging.dump\n'
printf 'Normal db:up will reuse this snapshot and skip after .local/payload-seed-state.env exists.\n'
