#!/bin/bash
#
# Déploiement PyramidCom sur o2switch.
#
# GitHub Actions compile Next.js et publie le résultat sur la branche
# « deploy ». Ce script récupère cette branche, copie le build dans
# l'application cPanel, installe uniquement les dépendances de production,
# puis demande à Passenger de redémarrer.

set -euo pipefail

REPO="$HOME/repositories/pyramidcom"
APP="$HOME/pyramidcom.fr/app"
NODEENV="$HOME/nodevenv/pyramidcom.fr/app/24/bin/activate"
MARQUEUR="$APP/.deployed_sha"
LOGFILE="$APP/tmp/deploy.log"
LOCKFILE="$HOME/pyramidcom.fr/data/deploy.lock"
HTACCESS="$HOME/pyramidcom.fr/.htaccess"

mkdir -p "$APP/tmp"

# CloudLinux/o2switch ne fournit pas toujours /dev/fd, ce qui rend la forme
# `exec > >(tee ...)` inutilisable. On relance une seule fois le script dans
# un pipeline classique afin de conserver à la fois la sortie terminal et le
# journal, sans dépendre de /dev/fd.
if [ "${PYRAMID_DEPLOY_LOGGED:-0}" != "1" ]; then
  export PYRAMID_DEPLOY_LOGGED=1
  set +e
  /bin/bash "$0" "$@" 2>&1 | tee -a "$LOGFILE"
  STATUS="${PIPESTATUS[0]}"
  exit "$STATUS"
fi

trap 'echo "[deploy] $(date -u +%Y-%m-%dT%H:%M:%SZ) — DÉPLOIEMENT ÉCHOUÉ (voir ci-dessus)"' ERR

mkdir -p "$(dirname "$LOCKFILE")"
exec 9>"$LOCKFILE"
if ! flock -n 9; then
  echo "[deploy] un autre déploiement PyramidCom est déjà en cours."
  exit 0
fi

cd "$REPO"
git fetch origin deploy --quiet

NOUVEAU="$(git rev-parse origin/deploy)"
ACTUEL="$(cat "$MARQUEUR" 2>/dev/null || echo none)"

if [ "$NOUVEAU" = "$ACTUEL" ]; then
  echo "[deploy] déjà à jour ($NOUVEAU), rien à faire."
  exit 0
fi

echo "[deploy] $(date -u +%Y-%m-%dT%H:%M:%SZ) — build $NOUVEAU détecté"

STAGING="$(mktemp -d "$HOME/tmp-pyramidcom-deploy.XXXXXX")"
cleanup() {
  case "$STAGING" in
    "$HOME"/tmp-pyramidcom-deploy.*) rm -rf -- "$STAGING" ;;
    *) echo "[deploy] dossier temporaire inattendu, nettoyage ignoré : $STAGING" ;;
  esac
}
trap cleanup EXIT

git archive origin/deploy | tar -x -C "$STAGING"

echo "[deploy] copie du build GitHub vers $APP"
rsync -a --no-perms --delete \
  --exclude='.git/' \
  --exclude='.github/' \
  --exclude='node_modules/' \
  --exclude='.env' \
  --exclude='.env.*' \
  --exclude='tmp/' \
  --exclude='data/' \
  --exclude='.deployed_sha' \
  "$STAGING/" "$APP/"

chmod 755 "$APP"

echo "[deploy] installation des dépendances de production"
cd "$APP"
set +u
# shellcheck disable=SC1090
source "$NODEENV"
set -u
npm ci --omit=dev

# Le groupe Passenger initial « production » est resté bloqué après les
# premiers échecs de spawn. Ce groupe versionné force un démarrage propre ;
# app.js remet ensuite explicitement NODE_ENV à production.
if ! grep -qxF "PassengerAppEnv pyramidcom-production-v2" "$HTACCESS"; then
  printf '\nPassengerAppEnv pyramidcom-production-v2\n' >> "$HTACCESS"
fi

touch "$APP/tmp/restart.txt"

echo "[deploy] contrôle de disponibilité"
HTTP_CODE="000"
for _ in 1 2 3 4 5; do
  HTTP_CODE="$(curl -sS -o /dev/null -w '%{http_code}' --max-time 15 https://pyramidcom.fr/ || true)"
  case "$HTTP_CODE" in
    2??|3??) break ;;
    *) sleep 2 ;;
  esac
done

case "$HTTP_CODE" in
  2??|3??) ;;
  *)
    echo "[deploy] contrôle HTTP en échec : $HTTP_CODE"
    exit 1
    ;;
esac

echo "$NOUVEAU" > "$MARQUEUR"
echo "[deploy] $(date -u +%Y-%m-%dT%H:%M:%SZ) — terminé, Passenger redémarré, HTTP $HTTP_CODE"
