#!/bin/bash
# ---------------------------------------------------------------------------
# RidinFamily — Interdire à Splash de supprimer un père de variantes Dolibarr.
#
# CRUDTrait::load() refuse déjà d'accéder à un père de variantes :
#
#     if (!$force && VariantsManager::hasProductVariants((int) $objectId)) {
#         return Splash::log()->errNull(Splash::trans("ProductIsVariantBase"));
#     }
#
# ...mais CRUDTrait::delete() n'a PAS ce garde-fou. Or un père de variantes ne
# porte aucune ligne de commande (les ventes sont sur ses enfants), donc
# Product::isObjectUsed() le déclare libre et Dolibarr accepte de le supprimer.
# Vérifié sur COURS25-STL (id 693) : 14 enfants, isObjectUsed = 0.
#
# Un appariement Splash qui résout vers un père — par exemple une variation
# WooCommerce portant le SKU de son parent — transforme alors une suppression
# anodine côté boutique en destruction d'une famille de variantes entière.
#
# Correctif : appliquer le même garde-fou au début de delete().
#
# N'affecte PAS le cas légitime déjà géré en fin de delete() : quand la dernière
# variante est supprimée, le père l'est aussi — à ce moment il n'a plus de
# combinaison, donc hasProductVariants() est faux et le garde-fou ne s'applique pas.
#
# Usage :  ./patch_splash_delete_guard.sh            # vérification seule
#          ./patch_splash_delete_guard.sh --apply    # sauvegarde + application
#          ./patch_splash_delete_guard.sh --revert   # restaure la sauvegarde
# ---------------------------------------------------------------------------
set -euo pipefail

F="$HOME/ridin/dolibarr/htdocs/custom/splash/src/Objects/Product/CRUDTrait.php"
BAKDIR="$HOME/_modbak_splashmsg"
MARKER="MODIF Pichinov : suppression d un pere de variantes interdite"
ACTION="${1:-}"

[ -f "$F" ] || { echo "ABSENT : $F"; exit 1; }
is_patched() { grep -q "$MARKER" "$F"; }

echo "=== Garde-fou sur la suppression de produit ==="
if is_patched; then echo "État : DÉJÀ patché"; else echo "État : NON patché"; fi

if [ "$ACTION" = "--revert" ]; then
  LAST=$(ls -1t "$BAKDIR"/CRUDTrait.php.* 2>/dev/null | head -1 || true)
  [ -n "$LAST" ] || { echo "Aucune sauvegarde dans $BAKDIR"; exit 1; }
  cp "$LAST" "$F"; echo "Restauré depuis $LAST"; php -l "$F"; exit 0
fi

if [ "$ACTION" != "--apply" ]; then
  echo; echo "Vérification seule. Relancer avec --apply pour sauvegarder et patcher."
  exit 0
fi
if is_patched; then echo "Rien à faire."; exit 0; fi

mkdir -p "$BAKDIR"
TS=$(date +%Y%m%d-%H%M%S)
cp "$F" "$BAKDIR/CRUDTrait.php.$TS"
echo "Sauvegarde : $BAKDIR/CRUDTrait.php.$TS"

php -r '
$f = $argv[1];
$src = file_get_contents($f);

$old = "    public function delete(string \$objectId): bool\n"
     . "    {\n"
     . "        global \$db,\$user;\n"
     . "        //====================================================================//\n"
     . "        // Stack Trace\n"
     . "        Splash::log()->trace();\n";

$new = "    public function delete(string \$objectId): bool\n"
     . "    {\n"
     . "        global \$db,\$user;\n"
     . "        //====================================================================//\n"
     . "        // Stack Trace\n"
     . "        Splash::log()->trace();\n"
     . "        //====================================================================//\n"
     . "        // MODIF Pichinov : suppression d un pere de variantes interdite.\n"
     . "        // Meme garde-fou que load() : un pere ne porte aucune ligne de\n"
     . "        // commande, donc isObjectUsed() le croit libre et Dolibarr le\n"
     . "        // supprimerait avec toute sa famille.\n"
     . "        if (VariantsManager::hasProductVariants((int) \$objectId)) {\n"
     . "            return Splash::log()->err(Splash::trans(\"ProductIsVariantBase\"));\n"
     . "        }\n";

$n = substr_count($src, $old);
if (1 !== $n) { fwrite(STDERR, "ARRET : motif trouve ".$n." fois (attendu 1)\n"); exit(1); }
file_put_contents($f, str_replace($old, $new, $src));
echo "Patch appliqué.\n";
' "$F"

echo "=== Lint ==="
php -l "$F"
echo "=== VariantsManager bien importé ? ==="
grep -c "use Splash\\\\Local\\\\Services\\\\VariantsManager\|VariantsManager" "$F" | head -1
