#!/usr/bin/env bash
# Bringt ein Plugin vom Entwicklungssystem auf ALLE Produktions-Frontends.
#
#   plugin-ausrollen.sh <PluginName> [--ohne-assets]
#
# Welche Knoten das sind, kommt aus dem Hetzner-Label "Webserver"
# (lib-knoten.sh). Vorher stand die Liste hier fest im Skript – ein dritter
# Knoten wäre still übersprungen worden und liefe weiter mit altem Code.
#
# Warum hier gebaut wird: auf den Frontends ist bewusst kein Node installiert
# (3,8 GB RAM, der Admin-Build allein braucht über 2 GB). Ausgeliefert wird
# das fertige Ergebnis – dafür muss VOR dem Aufruf bin/build-administration.sh
# gelaufen sein, sonst geht ein alter Stand raus.
#
# Die Datenbank ist ein Galera-Verbund: Migrationen laufen daher nur EINMAL,
# auf dem ersten Knoten. Der Zwischenspeicher wird dagegen überall geleert.
set -uo pipefail

# Alte Aufrufform abfangen: früher war das erste Argument der Zugangsordner.
if [ -d "${1:-}" ]; then
    echo "Hinweis: Der Zugangsordner wird nicht mehr gebraucht – angemeldet wird mit dem Schlüssel."
    shift
fi

PLUGIN="${1:?Pluginname fehlt, z. B. RiccardoSearch}"
OHNE_ASSETS="${2:-}"

QUELLE="/var/www/html/ShopwareDev/custom/plugins/$PLUGIN"
ZIEL="/var/www/riccardo/custom/plugins/$PLUGIN"
PHP="/usr/bin/php8.5"

[ -d "$QUELLE" ] || { echo "Plugin $PLUGIN gibt es hier nicht."; exit 1; }

cd "$(dirname "$0")"
source ./lib-knoten.sh
rz_pruefe_schluessel || exit 1

# Der Admin-Teil muss gebaut sein. Ein Plugin ohne Admin-Oberfläche hat den
# Ordner gar nicht – das ist in Ordnung, ein VERALTETER Stand wäre es nicht.
if [ -d "$QUELLE/src/Resources/app/administration" ] && [ ! -d "$QUELLE/src/Resources/public/administration" ]; then
    echo "Der Admin-Teil von $PLUGIN ist nicht gebaut. Erst: bin/build-administration.sh"
    exit 1
fi

mapfile -t KNOTEN < <(rz_knoten) || exit 1
set -- ${KNOTEN[0]}; LEIT_NAME="$1"; LEIT_IP="$2"
printf '== 0. Knoten: %d (%s), Migrationen auf %s\n' "${#KNOTEN[@]}" \
       "$(printf '%s ' "${KNOTEN[@]}" | tr -s ' ')" "$LEIT_NAME"

# Stimmt die Varnish-Löschliste noch mit den vorhandenen Knoten überein? Ein
# Knoten, der nicht darin steht, liefert nach jeder Änderung still veraltete
# Seiten aus.
./varnish-knoten.sh pruefen >/dev/null 2>&1 \
    || echo "   ACHTUNG: Varnish-Liste weicht ab – dev/deploy/varnish-knoten.sh setzen"

echo "== 1. Dateien übertragen"
for eintrag in "${KNOTEN[@]}"; do
    set -- $eintrag; name="$1"; ip="$2"
    # --delete, damit entfernte Dateien auch wirklich verschwinden; node_modules
    # und Quellkarten bleiben hier, die gehören nicht auf den Server.
    rsync -a --delete \
        --exclude 'node_modules' --exclude '*.map' --exclude '.git' \
        -e "$(rz_rsh)" "$QUELLE/" "root@$ip:$ZIEL/" \
        || { echo "Übertragung nach $name fehlgeschlagen"; exit 1; }
    echo "   $name: übertragen"
done

echo "== 2. Rechte"
for eintrag in "${KNOTEN[@]}"; do
    set -- $eintrag; rz_ssh "$2" "chown -R www-data:www-data $ZIEL"
done

echo "== 3. Plugin aktualisieren (nur $LEIT_NAME, die Datenbank ist gemeinsam)"
rz_ssh "$LEIT_IP" "cd /var/www/riccardo && sudo -u www-data $PHP bin/console plugin:refresh -q \
        && sudo -u www-data $PHP bin/console plugin:update $PLUGIN --no-interaction 2>&1 | tail -3"

if [ "$OHNE_ASSETS" != "--ohne-assets" ]; then
    echo "== 4. Assets in den Object Storage"
    rz_ssh "$LEIT_IP" "cd /var/www/riccardo && sudo -u www-data $PHP bin/console assets:install 2>&1 | tail -2"
    # Ohne diesen Schritt liegen die neuen Admin-Dateien unkomprimiert und ohne
    # Gültigkeitsdauer im Bucket.
    # --nur-assets: ein Plugin-Rollout aendert keine Medien. Ohne das laeuft
    # die Medien-Phase ueber zehntausende Objekte und der Rollout haengt.
    rz_ssh "$LEIT_IP" "TAGE=1 /usr/local/sbin/assets-optimieren.sh --nur-assets 2>&1 | tail -1"
fi

echo "== 5. Zwischenspeicher auf allen Knoten"
for eintrag in "${KNOTEN[@]}"; do
    set -- $eintrag; name="$1"; ip="$2"
    # cache:clear allein reicht nicht:
    #  - PHP-FPM hält den alten kompilierten Container im Opcache, bis die
    #    Arbeitsprozesse neu starten.
    #  - Das Entitäten-Schema für die Verwaltung liegt im Redis. Ohne das
    #    Leeren meldet der Admin "No definition found for entity type ...",
    #    obwohl die API die Entität längst kennt – ein Fehlerbild, das
    #    aussieht, als wäre das Plugin gar nicht angekommen.
    rz_ssh "$ip" "cd /var/www/riccardo && sudo -u www-data $PHP bin/console cache:clear -q \
        && sudo -u www-data $PHP bin/console cache:pool:clear cache.object -q \
        && systemctl reload php8.5-fpm && echo '   $name: geleert und FPM neu geladen'"
done

echo "== 6. Stand"
rz_ssh "$LEIT_IP" "cd /var/www/riccardo && sudo -u www-data $PHP bin/console plugin:list 2>/dev/null | grep -E \"^\\| $PLUGIN|$PLUGIN \" | head -2"
