#!/bin/bash
#
# RidinFamily — Remettre à niveau les fichiers restés en 21.0.2.
#
# CONSTAT
# L'arbre de production est un patchwork : la montée 21 → 23 a été faite en
# copiant une partie seulement des fichiers. Résultat, du code de la 21.0.2
# tourne aujourd'hui à côté du code de la 23.0.0 dans le même moteur —
# 76 fichiers de core/, 67 de includes/, 37 de admin/, 83 de install/.
#
# CE QUE FAIT CE SCRIPT
# Il remet à leur version 23.0.0 les fichiers qui sont RIGOUREUSEMENT IDENTIQUES
# à la 21.0.2. Cette identité est la preuve qu'ils ne portent aucune
# personnalisation : les toucher ne peut donc rien détruire.
#
# Les 180 fichiers réellement modifiés localement, eux, ne correspondent à
# aucune version officielle. Ils ne sont PAS dans le périmètre et ne seront
# pas touchés.
#
# COMMENT
# Par `git show 23.0.0:chemin > chemin`, et non `git checkout` : l'index git
# reste intact, seul le contenu du fichier est remplacé. Une sauvegarde des
# fichiers concernés est prise avant toute écriture.
#
# Usage (depuis ~/ridin/dolibarr) :
#   bash ~/dolfix/remise_a_niveau_23.sh            # simulation
#   bash ~/dolfix/remise_a_niveau_23.sh --apply    # remise à niveau
#
set -uo pipefail

CIBLE="23.0.0"
BASE="21.0.2"
REPO="$HOME/ridin/dolibarr"
APPLY=0
[ "${1:-}" = "--apply" ] && APPLY=1

cd "$REPO" || { echo "ARRET : $REPO introuvable."; exit 1; }

echo "=== Remise à niveau vers $CIBLE — mode $([ $APPLY -eq 1 ] && echo APPLICATION || echo SIMULATION) ==="
echo

# --- Garde-fous ---------------------------------------------------------------
for t in "$BASE" "$CIBLE"; do
  git rev-parse -q --verify "refs/tags/$t" >/dev/null || { echo "ARRET : tag $t absent."; exit 1; }
done
[ -f htdocs/version.inc.php ] || { echo "ARRET : ce n'est pas un arbre Dolibarr."; exit 1; }

# --- Constitution de la liste, recalculée à chaque exécution -------------------
echo "Analyse en cours (quelques minutes sur 3,6 Go)..."
LISTE=$(mktemp)
git diff --name-only "$CIBLE" -- htdocs 2>/dev/null \
  | grep -v '^htdocs/custom/' \
  | grep -v '^htdocs/conf/' \
  | grep -v '^htdocs/documents/' \
  | sort > "$LISTE.d23"
git diff --name-only "$BASE" -- htdocs 2>/dev/null | sort > "$LISTE.d21"

# Éligible = diffère de 23.0.0 ET identique à 21.0.2 (donc absent du diff 21.0.2)
comm -23 "$LISTE.d23" "$LISTE.d21" > "$LISTE"
NB=$(wc -l < "$LISTE")

echo
echo "Fichiers éligibles : $NB"
echo "  (différents de $CIBLE, mais rigoureusement identiques à $BASE)"
echo
echo "=== Répartition par répertoire ==="
sed 's|^htdocs/||; s|/.*||' "$LISTE" | sort | uniq -c | sort -rn | head -20 | sed 's/^/  /'

# --- Contrôle : aucun fichier personnalisé ne doit se glisser ici --------------
echo
echo "=== Contrôle d'innocuité ==="
SUSPECT=0
while read -r f; do
  if ! git diff --quiet "$BASE" -- "$f" 2>/dev/null; then
    echo "  /!\\ $f diffère de $BASE — exclu"
    SUSPECT=$((SUSPECT+1))
  fi
done < <(head -200 "$LISTE")
if [ "$SUSPECT" -eq 0 ]; then
  echo "  Les 200 premiers vérifiés un à un : tous identiques à $BASE."
else
  echo "  ARRET : $SUSPECT fichier(s) suspect(s)."
  exit 1
fi

if [ "$APPLY" -eq 0 ]; then
  cp "$LISTE" ~/dolfix/fichiers_a_remettre_a_niveau.txt
  echo
  echo "Liste complète écrite dans ~/dolfix/fichiers_a_remettre_a_niveau.txt"
  echo "Aucune écriture. Relancer avec --apply."
  rm -f "$LISTE" "$LISTE.d23" "$LISTE.d21"
  exit 0
fi

# --- Sauvegarde des fichiers concernés ----------------------------------------
SAUV="$HOME/ridin/backup-fichiers-avant-remise-a-niveau-$(date +%Y%m%d-%H%M%S).tar.gz"
echo
echo "=== Sauvegarde ==="
tar -czf "$SAUV" -T "$LISTE" 2>/dev/null
echo "  $SAUV  ($(du -h "$SAUV" | cut -f1), $(tar -tzf "$SAUV" | wc -l) fichiers)"

# --- Remise à niveau ----------------------------------------------------------
echo
echo "=== Remise à niveau ==="
OK=0; KO=0
while read -r f; do
  if git show "$CIBLE:$f" > "$f" 2>/dev/null; then
    OK=$((OK+1))
  else
    echo "  ERREUR : $f"
    KO=$((KO+1))
  fi
done < "$LISTE"
echo "  $OK fichiers remis à niveau, $KO erreur(s)"

# --- Contrôle final -----------------------------------------------------------
echo
echo "=== Contrôle ==="
RESTE=$(git diff --name-only "$CIBLE" -- htdocs 2>/dev/null | grep -v '^htdocs/custom/' | grep -vc '^htdocs/conf/')
echo "  fichiers du cœur différant encore de $CIBLE : $RESTE"
echo "  (attendu : les ~1 278 personnalisations réelles, dont 1 080 traductions)"
echo
php -l htdocs/master.inc.php >/dev/null 2>&1 && echo "  syntaxe de master.inc.php : OK" || echo "  /!\\ syntaxe de master.inc.php : ERREUR"
rm -f "$LISTE" "$LISTE.d23" "$LISTE.d21"
echo
echo "Pour revenir en arrière : tar -xzf $SAUV -C $REPO"
