#!/usr/bin/env bash
# -----------------------------------------------------------------------------
# migrations/apply.sh
#
# Applique les migrations SQL au conteneur donut-mariadb sur le serveur Donut.
# - Lit /srv/donut/secrets/mariadb.env pour le mot de passe root MariaDB
# - Lit /srv/donut/secrets/infolab.env pour DB_USER / DB_PASS / DB_NAME (app user)
# - Crée la BDD si absente, le user app si absent (idempotent), refresh le mot de passe
# - Trace les migrations appliquées dans la table `schema_migrations` :
#   chaque .sql n'est appliqué qu'une seule fois (relance => skip)
# - Affiche un résumé (tables présentes + count categories)
#
# Usage :
#   ./migrations/apply.sh
#
# Pré-requis sur l'hôte :
#   - docker disponible
#   - conteneur `donut-mariadb` en marche
#   - /srv/donut/secrets/{mariadb,infolab}.env lisibles par l'utilisateur courant
# -----------------------------------------------------------------------------
set -euo pipefail

DIR="$(cd "$(dirname "$0")" && pwd)"
MARIADB_ENV="${MARIADB_ENV:-/srv/donut/secrets/mariadb.env}"
INFOLAB_ENV="${INFOLAB_ENV:-/srv/donut/secrets/infolab.env}"
CONTAINER="${CONTAINER:-donut-mariadb}"

require_file() {
    if [[ ! -r "$1" ]]; then
        echo "ERR: fichier inaccessible : $1" >&2
        exit 1
    fi
}

env_get() {
    # Récupère la dernière occurrence de VAR=... dans un fichier .env (1er = à droite).
    local file="$1" var="$2"
    grep -E "^${var}=" "$file" | tail -n1 | cut -d= -f2- || true
}

require_file "$MARIADB_ENV"
require_file "$INFOLAB_ENV"

# Le secret root MariaDB peut être nommé MARIADB_ROOT_PASSWORD ou MYSQL_ROOT_PASSWORD.
ROOT_PWD="$(env_get "$MARIADB_ENV" MARIADB_ROOT_PASSWORD)"
if [[ -z "$ROOT_PWD" ]]; then
    ROOT_PWD="$(env_get "$MARIADB_ENV" MYSQL_ROOT_PASSWORD)"
fi
if [[ -z "$ROOT_PWD" ]]; then
    echo "ERR: ni MARIADB_ROOT_PASSWORD ni MYSQL_ROOT_PASSWORD trouvé dans $MARIADB_ENV" >&2
    exit 1
fi

APP_USER="$(env_get "$INFOLAB_ENV" DB_USER)"; APP_USER="${APP_USER:-infolab}"
APP_PASS="$(env_get "$INFOLAB_ENV" DB_PASS)"
APP_DB="$(env_get "$INFOLAB_ENV"   DB_NAME)"; APP_DB="${APP_DB:-infolab}"

if [[ -z "$APP_PASS" || "$APP_PASS" == "CHANGE_ME_STRONG_PASSWORD" ]]; then
    echo "ERR: DB_PASS vide ou non personnalisé dans $INFOLAB_ENV" >&2
    exit 1
fi

# Wrapper docker exec -> mariadb. Pas d'option -t (on streame du SQL via stdin).
mysql_root() {
    docker exec -i "$CONTAINER" mariadb -uroot -p"$ROOT_PWD" "$@"
}

# Test d'accès root avant d'aller plus loin.
if ! mysql_root -e 'SELECT 1' >/dev/null 2>&1; then
    echo "ERR: impossible de se connecter à $CONTAINER en root. Conteneur up ? mot de passe correct ?" >&2
    exit 1
fi

echo ">> [1/4] Création de la base \`$APP_DB\` et du user \`$APP_USER\`"
mysql_root <<SQL
CREATE DATABASE IF NOT EXISTS \`$APP_DB\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS '$APP_USER'@'%' IDENTIFIED BY '$APP_PASS';
ALTER USER '$APP_USER'@'%' IDENTIFIED BY '$APP_PASS';
GRANT ALL PRIVILEGES ON \`$APP_DB\`.* TO '$APP_USER'@'%';
FLUSH PRIVILEGES;
SQL

echo ">> [2/4] Bootstrap de la table schema_migrations (suivi des .sql appliqués)"
mysql_root "$APP_DB" <<'SQL'
CREATE TABLE IF NOT EXISTS schema_migrations (
    filename    VARCHAR(255) NOT NULL,
    applied_at  DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (filename)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
SQL

echo ">> [3/4] Application des migrations dans l'ordre alphabétique"
shopt -s nullglob
applied=0
skipped=0
for f in $(ls "$DIR"/*.sql 2>/dev/null | sort); do
    name="$(basename "$f")"
    # Skip si déjà appliquée (idempotent — on ne ré-applique pas).
    already="$(mysql_root "$APP_DB" -Nse "SELECT 1 FROM schema_migrations WHERE filename = '$name' LIMIT 1" 2>/dev/null || true)"
    if [[ -n "$already" ]]; then
        echo "   -- skip   $name (déjà appliquée)"
        skipped=$((skipped+1))
        continue
    fi
    echo "   -- apply  $name"
    mysql_root "$APP_DB" < "$f"
    mysql_root "$APP_DB" -e "INSERT INTO schema_migrations (filename) VALUES ('$name')"
    applied=$((applied+1))
done

echo ">> [4/4] Résumé"
mysql_root "$APP_DB" <<'SQL'
SELECT TABLE_NAME AS `table`
FROM information_schema.tables
WHERE TABLE_SCHEMA = DATABASE()
ORDER BY TABLE_NAME;
SELECT COUNT(*) AS categories_count FROM categories;
SQL

echo
echo "OK — migrations appliquées : $applied / sautées : $skipped"
