#!/usr/bin/env bash
# Fix B: set the Postgres role password to match POSTGRES_PASSWORD in .env (no volume wipe).
#
# Works when `psql` inside the container can connect to the server over the Unix socket
# without a password (common for the official postgres image’s local/trust rules). The app
# role (POSTGRES_USER) can change its own password, or you can set POSTGRES_SUPERUSER to
# connect as a different superuser (e.g. postgres) when that role still exists.
#
# Usage (repo root, stack can be up):
#   ./scripts/sync-postgres-app-password.sh
#
# Optional .env entries:
#   POSTGRES_SUPERUSER=postgres     # DB role to connect as (default: same as POSTGRES_USER)
#
set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
COMPOSE=(docker compose --env-file "${ROOT}/.env" -f "${ROOT}/docker-compose.prod.yml")
cd "$ROOT"

ENV_FILE="${ENV_FILE:-$ROOT/.env}"
if [[ ! -f "$ENV_FILE" ]]; then
  printf 'Missing %s\n' "$ENV_FILE" >&2
  exit 1
fi

while IFS= read -r line || [[ -n "$line" ]]; do
  line="${line%$'\r'}"
  [[ "$line" =~ ^[[:space:]]*# ]] && continue
  [[ "$line" =~ ^[[:space:]]*$ ]] && continue
  if [[ "$line" =~ ^([A-Za-z_][A-Za-z0-9_]*)=(.*)$ ]]; then
    key="${BASH_REMATCH[1]}"
    val="${BASH_REMATCH[2]}"
    val="${val#"${val%%[![:space:]]*}"}"
    val="${val%"${val##*[![:space:]]}"}"
    export "${key}=${val}"
  fi
done <"$ENV_FILE"

if [[ -z "${POSTGRES_USER:-}" || -z "${POSTGRES_PASSWORD:-}" ]]; then
  printf 'POSTGRES_USER and POSTGRES_PASSWORD must be set in %s\n' "$ENV_FILE" >&2
  exit 1
fi

# SQL string literal: escape single quotes per PostgreSQL rules (' -> '')
sql_escape_literal() {
  printf '%s' "$1" | sed "s/'/''/g"
}

# Double-quoted identifier: " -> "
sql_escape_ident() {
  printf '%s' "$1" | sed 's/"/""/g'
}

conn_role="${POSTGRES_SUPERUSER:-$POSTGRES_USER}"
pass_esc="$(sql_escape_literal "$POSTGRES_PASSWORD")"
user_ident="$(sql_escape_ident "$POSTGRES_USER")"

sql="ALTER ROLE \"${user_ident}\" WITH PASSWORD '${pass_esc}';"

printf '→ Connecting as Postgres role %q (inside container), updating password for role %q…\n' "$conn_role" "$POSTGRES_USER"

if "${COMPOSE[@]}" exec -T postgres psql -U "$conn_role" -d postgres -v ON_ERROR_STOP=1 -c "$sql"; then
  printf 'OK — role %q password now matches POSTGRES_PASSWORD in .env.\nRestart be0 if it was crash-looping:\n  %s restart be0\n' "$POSTGRES_USER" "${COMPOSE[*]}"
  exit 0
fi

printf '\nThat failed. Common causes:\n' >&2
printf '  • This cluster has no local "trust" for psql — supply the current password and run manually:\n' >&2
printf '      PGPASSWORD="(old)" docker compose --env-file .env -f docker-compose.prod.yml exec -T postgres \\\n' >&2
printf '        psql -U %q -d postgres -c "ALTER ROLE ..."\n' "$POSTGRES_USER" >&2
printf '  • Role %q is not a superuser and you connected as the wrong POSTGRES_SUPERUSER — set POSTGRES_SUPERUSER in .env to a superuser that exists.\n' "$POSTGRES_USER" >&2
printf '  • See docs/deploy-production-docker.md §3\n' >&2
exit 1
