#!/usr/bin/env bash
# =====================================================================
# Déploiement de sauvermonentreprise.fr sur l'hébergement mutualisé OVH.
# Usage : ./deploy/deploy-ovh.sh   (depuis la racine du projet, en local)
#
# Le mutualisé n'a ni git ni node : le build est fait ici et les fichiers
# sont poussés en rsync. Contrairement au VPS (deploy/deploy.sh), il n'y a
# pas de mode maintenance : le site répond pendant toute l'opération.
#
# D'où la règle essentielle de ce script : DEUX PASSES.
#   1. transfert SANS --delete  → les nouveaux assets versionnés arrivent
#      à côté des anciens ; à tout instant, les deux jeux sont servables ;
#   2. purge AVEC --delete      → les fichiers obsolètes ne partent qu'une
#      fois les nouveaux en place et les caches vidés.
#
# Une passe unique « rsync --delete » ouvre une fenêtre de plusieurs
# secondes pendant laquelle le CSS référencé par les pages a déjà été
# supprimé mais pas encore retransféré : le site s'affiche alors sans
# aucun style. C'est arrivé en production, ne pas revenir en arrière.
# =====================================================================
set -euo pipefail

# Rappel : ne jamais filtrer la sortie de ce script par « | grep | tail »
# sans vérifier ${PIPESTATUS[0]} — le code de sortie serait celui du filtre,
# et un échec passerait pour un succès. C'est arrivé une fois.

cd "$(dirname "$0")/.."

CIBLE="${DEPLOY_OVH_TARGET:-ovh:~/www/sauvermonentreprise/}"

# Jamais poussés : dépendances locales, secrets, base et journaux de production.
EXCLUSIONS=(
    --exclude '.git'
    --exclude 'node_modules'
    --exclude '.env'
    --exclude 'database/database.sqlite'
    --exclude 'storage/logs'
    --exclude 'storage/framework/cache'
    --exclude 'storage/framework/sessions'
    --exclude 'storage/framework/views'
    --exclude 'storage/sauvegardes'
    --exclude 'tests'
)

echo "→ Vérifications avant envoi"
php artisan test --quiet
npm run build

# Le manifeste doit exister, sinon Vite ne résout aucun asset côté serveur.
[ -f public/build/manifest.json ] || { echo "✗ public/build/manifest.json absent : build échoué." >&2; exit 1; }

echo "→ Passe 1/2 : transfert (sans suppression)"
rsync -az "${EXCLUSIONS[@]}" ./ "$CIBLE"

echo "→ Caches applicatifs"
# NE JAMAIS lancer « php artisan config:cache » sur ce mutualisé, ni ici ni à la
# main en SSH. Le compte est monté à deux endroits : SSH voit
# /home/baumberg-ssh/www/…, le serveur web voit /home/baumberg/www/…. Le cache
# de configuration fige des chemins ABSOLUS ; généré depuis SSH, il pointe le
# dossier des journaux vers une adresse que le web ne peut pas ouvrir, et tout
# le site tombe en 500 sans la moindre ligne de journal (Monolog échoue avant
# que Laravel puisse écrire). Incident du 5 août 2026, remis en état en
# supprimant bootstrap/cache/config.php. On ne garde donc que le nettoyage.
ssh "${CIBLE%%:*}" "cd ${CIBLE#*:} && php artisan migrate --force && php artisan optimize:clear"

echo "→ Passe 2/2 : purge des fichiers obsolètes"
rsync -az --delete "${EXCLUSIONS[@]}" ./ "$CIBLE"

echo "→ Contrôle du rendu"
URL="${DEPLOY_OVH_URL:-https://sauvermonentreprise.fr}"
# -L indispensable : quand le portail d'accès réservé est armé, la racine
# répond 302 vers /acces. Sans suivre la redirection, le corps est vide et le
# contrôle conclurait à tort que le site est servi sans style. La page du
# portail charge le même bundle, le contrôle reste donc probant dans les deux cas.
# --no-cache et un parametre unique : un cache intermediaire servant une page
# perimee ferait echouer le controle alors que le deploiement s'est bien passe.
# C'est arrive une fois, juste apres avoir corrige l'en-tete de cache.
# Trois tentatives espacées. Le second rsync passe en --delete : pendant
# quelques secondes, une page encore en cache peut référencer un bundle déjà
# supprimé. Le contrôle voyait alors un 404 et interrompait le script, ce qui
# sautait le git push qui suit. Un état transitoire ne doit pas être traité
# comme une panne, mais il ne doit pas non plus être ignoré : d'où la
# répétition plutôt que la suppression du contrôle.
CODE=""
for TENTATIVE in 1 2 3; do
    CSS=$(curl -fsSL -H 'Cache-Control: no-cache' -H 'Pragma: no-cache' "$URL?deploiement=$(date +%s)" \
        | grep -oE 'href="[^"]*/build/assets/app-[^"]*\.css"' | head -1 | sed 's/href="//;s/"$//')
    if [ -n "$CSS" ]; then
        CODE=$(curl -s -o /dev/null -w '%{http_code}' "$CSS")
        [ "$CODE" = "200" ] && break
    fi
    [ "$TENTATIVE" = "3" ] && break
    echo "  … contrôle du style, tentative $TENTATIVE sans succès, nouvel essai dans 10 s"
    sleep 10
done
[ -n "$CSS" ] || { echo "✗ Aucune feuille de style référencée sur $URL." >&2; exit 1; }
[ "$CODE" = "200" ] || { echo "✗ La feuille de style $CSS répond $CODE après trois tentatives." >&2; exit 1; }

echo "✓ Déploiement terminé, style servi ($CSS)."
