#!/usr/bin/env bash
# Contre-tests du déploiement (BE-46) : chaque refus attendu doit réellement refuser.
#
# Usage : bash scripts/contre-test-deploiement.sh
# Sortie : 0 si tous les refus tiennent, 1 sinon. N'écrit que dans un dossier temporaire.

set -uo pipefail

RACINE="$(cd "$(dirname "$0")/.." && pwd)"
cd "$RACINE"

BAC="$(mktemp -d "${TMPDIR:-/tmp}/contre-test-deploiement-XXXXXX")"
trap 'rm -rf "$BAC"' EXIT

ECHECS=0
CAS=0

# Chaque cas nomme ce qui doit être refusé : un contre-test qui passerait sans rien
# refuser ne vaut rien, donc on vérifie le code de sortie ET le motif du refus.
refuse() {
  local description="$1" motif="$2"; shift 2
  CAS=$((CAS + 1))
  local sortie code
  sortie="$("$@" 2>&1)"; code=$?
  if [[ "$code" -eq 0 ]]; then
    echo "ECHEC : $description — accepté alors qu'il fallait refuser." >&2
    ECHECS=1
  elif ! grep -qi -- "$motif" <<<"$sortie"; then
    echo "ECHEC : $description — refusé, mais pas pour la bonne raison :" >&2
    echo "$sortie" | sed 's/^/    /' >&2
    ECHECS=1
  else
    echo "ok   $description"
  fi
}

accepte() {
  local description="$1"; shift
  CAS=$((CAS + 1))
  if "$@" >/dev/null 2>&1; then
    echo "ok   $description"
  else
    echo "ECHEC : $description — refusé alors qu'il fallait accepter." >&2
    "$@" 2>&1 | sed 's/^/    /' >&2
    ECHECS=1
  fi
}

# ---------------------------------------------------------------- assembleur

: > "$BAC/artefact-inconnu.tar.gz"
refuse "une archive qui n'est pas celle de la CI est refusée sur son nom" \
  "nom d'archive inattendu" \
  bash scripts/assembler-artefact.sh "$BAC/artefact-inconnu.tar.gz"

# Une version qui commence par un point sortirait de `livraisons/` sur le serveur.
: > "$BAC/zedeca-auth-...tar.gz"
refuse "une version qui remonte d'un cran ('..') est refusée" \
  "version '..' invalide" \
  bash scripts/assembler-artefact.sh "$BAC/zedeca-auth-...tar.gz"

refuse "une archive absente est refusée" \
  "introuvable" \
  bash scripts/assembler-artefact.sh "$BAC/jamais-produite.tar.gz"

# ---------------------------------------------------------------- vérificateur

squelette() {
  local dist="$1"
  mkdir -p "$dist"/{config,routes,lang,vendor,bootstrap,public}
  touch "$dist"/{artisan,composer.json,composer.lock} \
        "$dist/config/app.php" "$dist/bootstrap/app.php" \
        "$dist/public/index.php" "$dist/vendor/autoload.php"
  printf 'ccc3333\n' > "$dist/VERSION"
}

DIST="$BAC/dist"
squelette "$DIST"
accepte "un artefact complet et sans secret est accepté" \
  bash scripts/verifier-artefact.sh "$DIST"

rm -f "$DIST/vendor/autoload.php"
refuse "un artefact amputé de son autochargeur est refusé" \
  "autochargeur" \
  bash scripts/verifier-artefact.sh "$DIST"
touch "$DIST/vendor/autoload.php"

printf 'APP_KEY=base64:secret\n' > "$DIST/.env"
refuse "un .env à la racine est refusé (DEP-16)" \
  "configuration d'environnement" \
  bash scripts/verifier-artefact.sh "$DIST"
rm -f "$DIST/.env"

# `publier-artefact.sh` fait `git add --force` : un secret imbriqué partirait dans
# l'historique du dépôt, que `exiger_absence .env` seul ne verrait pas.
printf 'DB_PASSWORD=secret\n' > "$DIST/config/.env"
refuse "un .env imbriqué est refusé" \
  "secret détecté" \
  bash scripts/verifier-artefact.sh "$DIST"
rm -f "$DIST/config/.env"

mkdir -p "$DIST/storage/oauth"
# En-tête PEM assemblé à l'exécution : écrit en clair ici, ce fichier serait lui-même
# signalé par le scan une fois empaqueté dans l'artefact (il l'a été une fois).
PEM_DEBUT="-----BEGIN RSA PRIVATE"; PEM_FIN="-----END RSA PRIVATE"
printf -- '%s KEY-----\nfactice\n%s KEY-----\n' "$PEM_DEBUT" "$PEM_FIN" \
  > "$DIST/storage/oauth/oauth-private.key"
refuse "la clé privée de signature des jetons est refusée" \
  "secret détecté\|clé privée" \
  bash scripts/verifier-artefact.sh "$DIST"
rm -rf "$DIST/storage"

mkdir -p "$DIST/vendor/composer"
printf '{"packages":[{"name": "phpunit/phpunit"}]}\n' > "$DIST/vendor/composer/installed.json"
refuse "un vendor/ qui embarque PHPUnit est refusé (artefact non --no-dev)" \
  "dépendances de développement" \
  bash scripts/verifier-artefact.sh "$DIST"
rm -f "$DIST/vendor/composer/installed.json"

printf '\n' > "$DIST/VERSION"
refuse "une VERSION vide est refusée" \
  "VERSION vide" \
  bash scripts/verifier-artefact.sh "$DIST"

# ---------------------------------------------------------------- .cpanel.yml

# Verrou de non-régression : le garde-fou qui empêche la cible de sortir de
# `livraisons/` doit rester en place. Sans lui, le `rsync --delete` qui suit efface
# toutes les livraisons, donc tout retour arrière (DEP-29).
CAS=$((CAS + 1))
if grep -q 'VERSION invalide' .cpanel.yml; then
  echo "ok   le .cpanel.yml borne encore la VERSION avant d'en faire un chemin"
else
  echo "ECHEC : garde-fou de VERSION absent du .cpanel.yml — la cible peut sortir de livraisons/." >&2
  ECHECS=1
fi

echo
if [[ "$ECHECS" -ne 0 ]]; then
  echo "Contre-tests de déploiement : ÉCHEC ($CAS cas)." >&2
  exit 1
fi
echo "Contre-tests de déploiement : $CAS cas, tous conformes."
