#!/usr/bin/env bash
# Spielt das Umzugspaket auf einem Frontend des Produktionsverbunds ein.
# Läuft AUF dem Frontend, als root.
#
# Aufruf: shop-import.sh <paketordner> <domain> [zielordner] [datenbank]
#
# Erwartet im Zielordner eine ausgefüllte .env.local (Vorlage: env.prod.template).
# Ohne --uebernehmen wird nur geprüft und nichts geschrieben.
set -euo pipefail

PAKET="${1:?Paketordner fehlt}"
DOMAIN="${2:?Zieladresse fehlt}"
ZIEL="${3:-/var/www/riccardo}"
DBNAME="${4:-riccardo_shop}"
MODUS="${MODUS:-pruefen}"   # MODUS=uebernehmen für echte Ausführung
HIER="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"   # Ordner mit prod-config

log()  { printf '\n\033[1m== %s\033[0m\n' "$*"; }
tun()  { if [ "$MODUS" = uebernehmen ]; then eval "$@"; else echo "  [würde tun] $*"; fi; }
# Der Verbund laeuft auf PHP 8.5, die Standard-"php" auf den Frontends ist
# aber 8.3 (fuer die Altanwendungen auf derselben Maschine). Wer das nicht
# festlegt, laesst composer und bin/console mit der falschen Fassung laufen -
# composer bricht dann an der composer.lock ab ("requires php >=8.4").
PHPBIN="$(command -v php8.5 || command -v php)"
sw()   { sudo -u www-data "$PHPBIN" "$ZIEL/bin/console" "$@"; }

log "Paket prüfen"
CODE=$(ls "$PAKET"/code/code-*.tar.gz 2>/dev/null | head -1)
DUMP=$(ls "$PAKET"/datenbank/*.sql.gz 2>/dev/null | head -1)
[ -f "$CODE" ] || { echo "Code-Archiv fehlt"; exit 1; }
[ -f "$DUMP" ] || { echo "Datenbank-Dump fehlt"; exit 1; }
echo "  Code: $(basename "$CODE") ($(du -h "$CODE" | cut -f1))"
echo "  Dump: $(basename "$DUMP") ($(du -h "$DUMP" | cut -f1))"
( cd "$PAKET" && sha256sum -c pruefsummen.sha256 --quiet ) && echo "  Prüfsummen stimmen"

log "Platz und Werkzeuge"
frei=$(df --output=avail -BG / | tail -1 | tr -dc '0-9')
echo "  $frei GB frei (gebraucht werden rund 8 GB)"
[ "$frei" -ge 10 ] || { echo "  zu wenig Platz"; exit 1; }
php -v | head -1 | sed 's/^/  /'
composer --version | head -1 | sed 's/^/  /'
command -v mariadb >/dev/null || echo "  HINWEIS: kein MariaDB-Client – für den Import nötig (apt install mariadb-client)"

log "Code auspacken nach $ZIEL"
# Zweiter Riegel: falls ein aelteres Paket die Dev-Konfiguration doch
# enthaelt, wird sie beim Auspacken uebersprungen. Die .env.local des
# Zielsystems ist das Einzige, was den Shop an DIESEN Verbund bindet.
# Ausgepackt wird IMMER erst daneben, nie ueber den laufenden Shop.
tun "rm -rf /var/www/.rz-neu && mkdir -p /var/www/.rz-neu && tar xzf '$CODE' -C /var/www/.rz-neu --exclude='*/.env.local' --exclude='*/.env.local.php' --exclude='*/.env.dev'"

if [ -d "$ZIEL" ]; then
    # Das Ziel gibt es schon: abgleichen statt verschieben. Ein "mv" wuerde den
    # neuen Baum IN den alten hineinlegen (/var/www/riccardo/ShopwareDev) -
    # der Shop liefe danach unveraendert weiter und niemand saehe warum.
    #
    # Ausgenommen bleibt, was diesen Knoten ausmacht oder zur Laufzeit
    # entsteht: Konfiguration, Zwischenspeicher, Protokolle, Abhaengigkeiten
    # und die Medien.
    echo "  $ZIEL gibt es bereits - es wird abgeglichen (rsync), nicht ersetzt"
    tun "rsync -a --delete \
        --exclude '.env.local' --exclude '.env.local.php' --exclude '.env.dev' \
        --exclude 'var/' --exclude 'vendor/' --exclude 'node_modules/' \
        --exclude 'public/media/' --exclude 'public/thumbnail/' --exclude 'public/sitemap/' \
        --exclude 'config/packages/varnish.yaml' \
        /var/www/.rz-neu/ShopwareDev/ '$ZIEL/'"
else
    tun "mv /var/www/.rz-neu/ShopwareDev '$ZIEL'"
fi
tun "rm -rf /var/www/.rz-neu"
tun "chown -R www-data:www-data '$ZIEL'"

log "Abhängigkeiten installieren (ohne Entwicklungspakete)"
tun "cd '$ZIEL' && sudo -u www-data COMPOSER_HOME='$ZIEL/var/cache/composer' $PHPBIN \$(command -v composer) install --no-dev --optimize-autoloader --no-interaction"

log "Konfiguration für den Verbund einsetzen"
for f in storage.yaml redis.yaml; do
    tun "install -o www-data -g www-data -m 644 '$HIER/prod-config/$f' '$ZIEL/config/packages/$f'"
done
if [ -f "$ZIEL/.env.local" ]; then
    echo "  .env.local vorhanden"
    for k in APP_SECRET APP_URL DATABASE_URL REDIS_URL S3_BUCKET_PUBLIC MAILER_DSN TRUSTED_HOSTS; do
        grep -q "^$k=" "$ZIEL/.env.local" && echo "    $k gesetzt" || echo "    FEHLT: $k"
    done
else
    echo "  .env.local fehlt – aus dev/deploy/prod-config/env.prod.template erzeugen und ausfüllen"
    [ "$MODUS" = uebernehmen ] && exit 1
fi
# Die Entwicklungs-Konfiguration darf nicht mitkommen
tun "rm -f '$ZIEL/.env.local.php' '$ZIEL/config/packages/dev' -r"

# Auf einem zweiten Knoten wird die Datenbank NICHT noch einmal eingespielt:
# der Galera-Verbund ist gemeinsam, ein zweiter Import wuerde den Stand des
# ersten Knotens ueberschreiben - samt allem, was seitdem passiert ist.
if [ "${OHNE_DB:-0}" = 1 ]; then
    log "Datenbank uebersprungen (OHNE_DB=1, gemeinsamer Galera-Verbund)"
else
log "Datenbank einspielen"
# Der Zugang kommt aus der .env.local des ZIELSYSTEMS, nicht aus dem Paket.
#
# Ein blosses "mariadb" wuerde den lokalen Socket suchen - auf den Frontends
# laeuft aber kein Datenbankdienst, die Galera-Knoten liegen unter 10.0.3.x.
# Beim ersten Umzug fiel das nicht auf, weil die Datenbank damals von Hand
# eingespielt wurde.
if [ -f "$ZIEL/.env.local" ]; then
    eval "$(python3 - "$ZIEL/.env.local" <<'PYEOF'
import re, sys, shlex
from urllib.parse import urlparse, unquote
inhalt = open(sys.argv[1], encoding='utf-8').read()
treffer = re.search(r'^DATABASE_URL=(.+)$', inhalt, re.M)
if not treffer:
    sys.exit(0)
u = urlparse(treffer.group(1).strip().strip('"\''))
for name, wert in (('DBHOST', u.hostname or ''), ('DBPORT', str(u.port or 3306)),
                   ('DBUSER', unquote(u.username or '')), ('DBPASS', unquote(u.password or '')),
                   ('DBNAME_ENV', (u.path or '/').lstrip('/'))):
    print('%s=%s' % (name, shlex.quote(wert)))
PYEOF
)"
fi
DBNAME="${DBNAME_ENV:-$DBNAME}"
[ -n "${DBHOST:-}" ] || { echo "  Kein DATABASE_URL in $ZIEL/.env.local - Abbruch"; exit 1; }
echo "  Ziel: $DBUSER@$DBHOST:$DBPORT, Datenbank $DBNAME"

# Zugangsdaten nur ueber eine Optionsdatei, nie auf der Befehlszeile: dort
# stuenden sie fuer jeden in der Prozessliste.
OPTDATEI=$(mktemp); chmod 600 "$OPTDATEI"
trap 'rm -f "$OPTDATEI"' EXIT
printf '[client]\nhost=%s\nport=%s\nuser=%s\npassword=%s\n' \
    "$DBHOST" "$DBPORT" "$DBUSER" "$DBPASS" > "$OPTDATEI"

if [ "$MODUS" = uebernehmen ]; then
    mariadb --defaults-extra-file="$OPTDATEI" -e "SELECT 1" >/dev/null \
        || { echo "  Keine Verbindung zur Datenbank - Abbruch"; exit 1; }
    echo "  Verbindung steht"
fi

tun "mariadb --defaults-extra-file='$OPTDATEI' -e 'CREATE DATABASE IF NOT EXISTS \`$DBNAME\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci'"
tun "zcat '$DUMP' | mariadb --defaults-extra-file='$OPTDATEI' '$DBNAME'"

# Die Integration der Wawi ueberlebt den Import: sie haelt den Konnektor am
# Leben und steht im Dump mit dem SCHLUESSEL DES ENTWICKLUNGSSYSTEMS.
#
# Zurueckgespielt wird aber NUR die Zeile der Wawi, nicht die ganze Tabelle.
# Der erste Uebertrag am 25.09.2026 hat die Datei komplett eingespielt und
# damit alle uebrigen Integrationen des Dev-Standes weggeraeumt - darunter
# die, mit denen die Skripte hier gegen die Admin-API sprechen. Der Shop lief
# weiter, aber jeder API-Aufruf gegen die Produktion antwortete nur noch mit
# "Client authentication failed", und der Grund lag drei Schritte vorher.
#
# Die Datei ist ein voller Tabellen-Dump (DROP, CREATE, INSERT) - sie
# einzuspielen heisst, die Tabelle zu ersetzen. Darum wird sie unter anderem
# Namen geladen und daraus nur die Wawi uebernommen.
SICHERUNG=$(cat /root/.rz-letzte-sicherung 2>/dev/null || true)
if [ -n "$SICHERUNG" ] && [ -f "$SICHERUNG/integration.sql" ]; then
    echo "  Integration der Wawi wird aus $SICHERUNG/integration.sql zurueckgespielt"
    tun "sed 's/\`integration\`/\`rz_integration_sicherung\`/g' '$SICHERUNG/integration.sql' \
        | mariadb --defaults-extra-file='$OPTDATEI' '$DBNAME'"
    tun "mariadb --defaults-extra-file='$OPTDATEI' '$DBNAME' -e \
        \"REPLACE INTO integration SELECT * FROM rz_integration_sicherung WHERE label = 'JTL'; \
          DROP TABLE IF EXISTS rz_integration_sicherung;\""
    tun "mariadb --defaults-extra-file='$OPTDATEI' '$DBNAME' -e \
        'SELECT CONCAT(\"  Integrationen danach: \", COUNT(*)) FROM integration' -sN"
else
    echo "  ACHTUNG: keine gesicherte integration.sql gefunden - der Wawi-Abgleich"
    echo "           wird nach dem Import NICHT mehr funktionieren, bis der"
    echo "           Zugangsschluessel von Hand gesetzt ist."
fi

tun "sed 's|<domain>|$DOMAIN|g' '$HIER/prod-config/prod-anpassungen.sql' | mariadb --defaults-extra-file='$OPTDATEI' '$DBNAME'"

# Medienadressen in CMS-Bloecken absolut machen.
#
# In den HTML-Bloecken stehen Adressen wie /thumbnail/b2/1a/02/…/rz-10038.webp.
# Auf der Entwicklungsmaschine funktionieren die, weil die Medien dort unter
# public/ liegen. Hier liegen sie im Object Storage - jeder relative Pfad
# laeuft ins Leere, und auf der Startseite bleiben Bilderrahmen uebrig.
#
# Genau wie die Domain ist das ein Wert, der je Umgebung ein anderer ist und
# nach JEDEM Uebertrag gesetzt werden muss. Am 25.09.2026 ist es nach dem
# ersten Uebertrag tagelang niemandem aufgefallen.
if [ -f "$HIER/../daten/cms-medien-absolut.php" ]; then
    tun "$PHPBIN '$HIER/../daten/cms-medien-absolut.php' '$ZIEL' --schreiben"
else
    echo "  ACHTUNG: cms-medien-absolut.php fehlt - relative Bildadressen in"
    echo "           CMS-Bloecken bleiben kaputt."
fi

fi

log "Shopware vorbereiten"
tun "sw cache:clear"
tun "sw assets:install"
tun "sw plugin:refresh"
tun "sw theme:compile"
if [ "${OHNE_DB:-0}" = 1 ]; then
    echo "  Indexlauf uebersprungen - den hat der erste Knoten schon gemacht"
else
    tun "sw dal:refresh:index --skip=product.stream.indexer"
fi
tun "sw scheduled-task:register"

log "Dienste"
echo "  Worker und Planer werden über die Vorlagen in dev/deploy/prod-config eingerichtet:"
echo "    rz-worker@.service, rz-scheduler.service, nginx-riccardo.conf"
tun "install -m 644 '$HIER/prod-config/rz-worker@.service' /etc/systemd/system/"
tun "install -m 644 '$HIER/prod-config/rz-scheduler.service' /etc/systemd/system/"
tun "systemctl daemon-reload"

log "Fertig ($MODUS)"
echo "  Nächste Schritte: nginx-Site aktivieren, Worker starten, Startseite prüfen."
