#!/usr/bin/env bash
# Prépare le Postgres Homebrew (postgresql@18) pour seoinsight : rôle `seoinsight` (LOGIN,
# CREATEDB) et bases `seoinsight_auth`, `seoinsight_data`, `seoinsight_data_test` dont il est
# propriétaire. Le préfixe est délibéré : cette instance Postgres est partagée entre projets,
# et des noms nus (`auth`, `data`) seraient repris tels quels par le suivant — une base AUTH
# mélangée entre deux projets, ce sont des comptes et des sessions qui se croisent.
# Idempotent : relançable à volonté. Ne touche à rien d'autre (la base `advmfr_hr` d'un
# autre projet cohabite sur la même instance).
#
# Prérequis : brew services start postgresql@18
# Usage     : mise run db-init   (ou scripts/db-init.sh, depuis n'importe quel répertoire)
# Variables : PGHOST (défaut /tmp = socket brew), PGPORT (défaut 5432),
#             PGSUPERUSER (défaut : utilisateur courant, superuser de l'instance brew),
#             DB_INIT_AGENT_SLOTS (défaut 0) : crée en plus N bases
#             `seoinsight_data_test_a1`..`aN`. Deux suites pytest lancées en parallèle sur
#             la même base se volent leurs jobs et leurs lignes (cf. le commentaire de
#             `_purge_leftover_test_jobs` dans api/tests/conftest.py) ; un agent qui doit
#             travailler pendant qu'un autre teste prend une de ces bases via
#             `PYTEST_DATABASE_URL`.
set -euo pipefail

if [ -d /opt/homebrew/opt/postgresql@18/bin ]; then
  export PATH="/opt/homebrew/opt/postgresql@18/bin:$PATH"
fi

PGHOST="${PGHOST:-/tmp}"
PGPORT="${PGPORT:-5432}"
PGSUPERUSER="${PGSUPERUSER:-$(id -un)}"
ROLE="seoinsight"
ROLE_PASSWORD="seoinsight"
DATABASES=(seoinsight_auth seoinsight_data seoinsight_data_test)
DATA_DATABASES=(seoinsight_data seoinsight_data_test)

for slot in $(seq 1 "${DB_INIT_AGENT_SLOTS:-0}"); do
  DATABASES+=("seoinsight_data_test_a$slot")
  DATA_DATABASES+=("seoinsight_data_test_a$slot")
done

if ! pg_isready -h "$PGHOST" -p "$PGPORT" -q; then
  echo "Postgres injoignable sur $PGHOST:$PGPORT. Lancer : brew services start postgresql@18" >&2
  exit 1
fi

admin() {
  psql -X -q -v ON_ERROR_STOP=1 -h "$PGHOST" -p "$PGPORT" -U "$PGSUPERUSER" -d postgres "$@"
}

if [ "$(admin -tAc "SELECT 1 FROM pg_roles WHERE rolname = '$ROLE'")" = "1" ]; then
  echo "rôle $ROLE : déjà présent"
else
  admin -c "CREATE ROLE $ROLE LOGIN PASSWORD '$ROLE_PASSWORD' CREATEDB"
  echo "rôle $ROLE : créé"
fi

for db in "${DATABASES[@]}"; do
  if [ "$(admin -tAc "SELECT 1 FROM pg_database WHERE datname = '$db'")" = "1" ]; then
    echo "base $db : déjà présente"
  else
    createdb -h "$PGHOST" -p "$PGPORT" -U "$PGSUPERUSER" -O "$ROLE" "$db"
    echo "base $db : créée (propriétaire $ROLE)"
  fi
done

# Extensions des bases DATA, exigées par la migration `keywords` (module Imports) :
#   pg_trgm → repli flou de la recherche du réservoir ; vector → type halfvec(1024) de
#   `keywords.embedding`.
# Posées ici, en superutilisateur, et **hors du schéma `public`** :
#   - `vector` n'est pas une extension « trusted » : le rôle seoinsight ne peut pas la
#     créer lui-même, la migration ne fait que constater sa présence ;
#   - `app.db_reset` recrée `public` : une extension qui y vivrait serait emportée, et la
#     migration suivante échouerait faute de pouvoir la réinstaller.
# `search_path` de la base les rend visibles sans qualification (`halfvec`, `gin_trgm_ops`).
for db in "${DATA_DATABASES[@]}"; do
  psql -X -q -v ON_ERROR_STOP=1 -h "$PGHOST" -p "$PGPORT" -U "$PGSUPERUSER" -d "$db" \
    -c "SET client_min_messages = warning;
        CREATE SCHEMA IF NOT EXISTS extensions;
        GRANT USAGE ON SCHEMA extensions TO $ROLE;
        CREATE EXTENSION IF NOT EXISTS pg_trgm SCHEMA extensions;
        CREATE EXTENSION IF NOT EXISTS vector SCHEMA extensions;
        ALTER DATABASE $db SET search_path = public, extensions;"
  echo "base $db : extensions pg_trgm + vector (schéma extensions)"
done

# Vérification finale par le chemin qu'utilisent les apps (TCP localhost, rôle seoinsight).
for db in "${DATABASES[@]}"; do
  psql -X -q -v ON_ERROR_STOP=1 -h localhost -p "$PGPORT" -U "$ROLE" -d "$db" -c "SELECT 1" >/dev/null
done
echo "OK : $ROLE se connecte à ${DATABASES[*]} sur localhost:$PGPORT"
