#!/usr/bin/env bash
# Passt den PHP-Opcache auf allen Frontends an Shopware an.
#
#   opcache-stellen.sh zeigen
#   opcache-stellen.sh setzen
#
# Warum: die Frontends liefen mit den PHP-Vorgaben.
#
#   max_accelerated_files  10.000   bei 21.714 PHP-Dateien im Shop
#   memory_consumption      128 MB  fuer eine Anwendung dieser Groesse zu klein
#   interned_strings_buffer   8 MB  Vorgabe, Shopware braucht mehr
#
# Passt der uebersetzte Code nicht in den Cache, wird er bei jedem Aufruf neu
# uebersetzt - und zwar genau dann am meisten, wenn viele verschiedene Seiten
# gleichzeitig aufgerufen werden. Im Lasttest am 25.09.2026 war die CPU der
# Frontends der Engpass; das hier ist der erste Ort, an dem man CPU-Zeit
# zurueckbekommt, ohne eine Zeile Code zu aendern.
#
# validate_timestamps bleibt bewusst AN. Das Abschalten braechte noch ein paar
# Prozent, aber dann wirkt keine Dateiaenderung mehr ohne FPM-Neustart - und
# ein Shop, der alten Code ausliefert, obwohl die Datei neu ist, kostet mehr
# Zeit beim Suchen als er beim Ausliefern spart.
set -uo pipefail

BEFEHL="${1:-zeigen}"
DATEI=/etc/php/8.5/fpm/conf.d/99-riccardo-opcache.ini

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

mapfile -t KNOTEN < <(rz_knoten) || exit 1

for eintrag in "${KNOTEN[@]}"; do
    set -- $eintrag; name="$1"; ip="$2"
    printf '  %-12s ' "$name"

    if [ "$BEFEHL" != setzen ]; then
        rz_ssh "$ip" "
            PHP_INI_SCAN_DIR=/etc/php/8.5/fpm/conf.d /usr/bin/php8.5 -i 2>/dev/null | awk -F' => ' '
              /^opcache.memory_consumption/      {m=\$2}
              /^opcache.max_accelerated_files/   {d=\$2}
              /^opcache.interned_strings_buffer/ {z=\$2}
              /^opcache.validate_timestamps/     {v=\$2}
              END {printf \"Speicher=%s MB  Dateien=%s  Zeichenketten=%s MB  Zeitstempelpruefung=%s\n\", m, d, z, v}'
        "
        continue
    fi

    rz_ssh "$ip" "
        set -e
        dateien=\$(find /var/www/riccardo -name '*.php' -not -path '*/var/cache/*' | wc -l)
        cat > $DATEI <<CONF
; ERZEUGT von dev/deploy/opcache-stellen.sh - nicht von Hand aendern.
;
; Die PHP-Vorgaben sind fuer eine Anwendung mit \$dateien Dateien zu klein.
; Passt der uebersetzte Code nicht hinein, wird er staendig neu uebersetzt -
; und das kostet genau die CPU, die unter Last fehlt.
;
; Der Speicher ist GETEILT: die Zahl faellt einmal an, nicht je Arbeiter.
opcache.memory_consumption = 384
opcache.max_accelerated_files = 30011
opcache.interned_strings_buffer = 24

; Bleibt an: sonst wirkt keine Dateiaenderung ohne FPM-Neustart.
opcache.validate_timestamps = 1
opcache.revalidate_freq = 60
CONF
        /usr/bin/php8.5 --ini 2>/dev/null >/dev/null
        systemctl reload php8.5-fpm
        sleep 2
        PHP_INI_SCAN_DIR=/etc/php/8.5/fpm/conf.d /usr/bin/php8.5 -i 2>/dev/null | awk -F' => ' '
          /^opcache.memory_consumption/    {m=\$2}
          /^opcache.max_accelerated_files/ {d=\$2}
          END {printf \"Dateien im Shop: %s, Cache jetzt fuer %s Dateien und %s MB\n\", \"'\"\$dateien\"'\", d, m}'
    " || { echo "    fehlgeschlagen"; exit 1; }
done

if [ "$BEFEHL" = setzen ]; then
    echo "  Gegenprobe:"
    for eintrag in "${KNOTEN[@]}"; do
        set -- $eintrag
        rz_ssh "$2" "curl -s -o /dev/null -w '    $1 Shop: %{http_code}\n' -H 'Host: shop.riccardo-zigarette.de' http://127.0.0.1/"
    done
fi
