#!/usr/bin/env bash
# onx-vhost-add-nginx — Create an Nginx vhost from template.
#
# Called by onx-vhost-add dispatcher when 'server' = 'nginx'.
# Supports reverse_proxy mode (Nginx önde + Apache arkada).
#
# Input (stdin JSON) — same as onx-vhost-add.
# Output (stdout JSON):
#   {"vhost_path":..., "reloaded":true, "ssl_enabled":..., "server":"nginx", "reverse_proxy":...}
#
# Exit codes: 0=ok 1=invalid-input 2=preflight-fail 3=exec-fail 4=rolled-back

set -euo pipefail

SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
# shellcheck source=_lib/common.sh
source "${SCRIPT_DIR}/_lib/common.sh"

# ── Constants ────────────────────────────────────────────────────────────────
TEMPLATE_PATH="/usr/local/onoxsoft/templates/vhost-nginx.conf.stub"
TEMPLATE_HTTPS_PATH="/usr/local/onoxsoft/templates/nginx-https.conf.stub"
TEMPLATE_RP_PATH="/usr/local/onoxsoft/templates/vhost-reverse-proxy.conf.stub"
TEMPLATE_RP_HTTPS_PATH="/usr/local/onoxsoft/templates/nginx-reverse-proxy-https.conf.stub"
VHOST_DIR="/etc/nginx/conf.d/sites"
# v77.15: System subdomain (webmail/mail/panel/webdisk/autoconfig/autodiscover)
# Roundcube + autodiscover PHP handler PANEL pool socket'inden çalışmalı
# (müşteri pool open_basedir Roundcube/autodiscover path'lerine izin vermez).
ROUNDCUBE_PATH="/usr/share/roundcubemail"
AUTODISCOVER_PATH="/usr/local/onoxsoft/autodiscover"
PANEL_FPM_SOCK="/var/opt/remi/php82/run/php-fpm/onoxsoft-panel.sock"

# ── Read & parse stdin ───────────────────────────────────────────────────────
INPUT=$(cat)
onx_require_json "${INPUT}"

USERNAME=$(onx_json_get "${INPUT}" "username")
DOMAIN=$(onx_json_get "${INPUT}" "domain")
DOC_ROOT=$(onx_json_get "${INPUT}" "doc_root")
PHP_VERSION=$(onx_json_get "${INPUT}" "php_version" "8.2")
SSL_ENABLED=$(onx_json_get_bool "${INPUT}" "ssl_enabled" "false")
CERT_PATH=$(onx_json_get "${INPUT}" "cert_path" "")
KEY_PATH=$(onx_json_get "${INPUT}" "key_path" "")
REVERSE_PROXY=$(onx_json_get_bool "${INPUT}" "reverse_proxy" "false")
# v72.3: bulk migration mode — reload skip (caller sonunda tek seferde reload eder)
SKIP_RELOAD=$(onx_json_get_bool "${INPUT}" "skip_reload" "false")

# v77.15: System subdomain mode (webmail/mail/panel/webdisk/autoconfig/autodiscover)
# Caddy v82.1 ve OLS v79.2 pattern paralel — SystemSubdomainProvisioner her
# domain için 6 subdomain (4 type) ekler. Type'a göre özel server block üretir,
# PHP handler = panel pool socket (open_basedir uyumluluk), cert lookup =
# PARENT_DOMAIN üzerinden (multi-SAN cert tüm 7 hostname'i kapsar).
IS_SYSTEM_SUBDOMAIN=$(onx_json_get_bool "${INPUT}" "is_system_subdomain" "false")
SUBDOMAIN_TYPE=$(onx_json_get "${INPUT}" "subdomain_type" "")
PARENT_DOMAIN=$(onx_json_get "${INPUT}" "parent_domain" "")
REDIRECT_TO=$(onx_json_get "${INPUT}" "redirect_to" "")

# ── Input validation ─────────────────────────────────────────────────────────
onx_validate_username "${USERNAME}"

# Runtime detect home directory (handles /home/users/<user> vs /home/<user>)
USER_HOME=$(onx_resolve_home "${USERNAME}" 2>/dev/null || echo "/home/${USERNAME}")

onx_validate_domain "${DOMAIN}"

[[ -z "${DOC_ROOT}" ]] && onx_die 1 "doc_root is required"

PHP_VERSION_NODOT="${PHP_VERSION//./}"

# ── Preflight ────────────────────────────────────────────────────────────────
mkdir -p "${VHOST_DIR}"
command -v nginx >/dev/null 2>&1 || onx_die 2 "nginx not found"

# v77.15: System subdomain modu — template/USER_HOME check'leri SKIP, normal
# vhost'ta gerekli. Subdomain için docroot Roundcube/autodiscover (sistem dizini)
# olabilir, USER_HOME hala log path için kontrol edilir AMA system subdomain
# kendi log dizinini (/var/log/onoxsoft-system) kullanır.
if [[ "${IS_SYSTEM_SUBDOMAIN}" != "true" ]]; then
  if [[ "${REVERSE_PROXY}" == "true" ]]; then
    [[ -f "${TEMPLATE_RP_PATH}" ]] || onx_die 2 "reverse-proxy template not found: ${TEMPLATE_RP_PATH}"
  else
    [[ -f "${TEMPLATE_PATH}" ]] || onx_die 2 "nginx template not found: ${TEMPLATE_PATH}"
  fi
  [[ -d "${USER_HOME}" ]] || onx_die 2 "home directory not found: ${USER_HOME}"
  mkdir -p "${USER_HOME}/logs"
fi

if [[ "${SSL_ENABLED}" == "true" ]]; then
  [[ -n "${CERT_PATH}" ]] || onx_die 1 "cert_path required when ssl_enabled"
  [[ -n "${KEY_PATH}" ]]  || onx_die 1 "key_path required when ssl_enabled"
  [[ -f "${CERT_PATH}" ]] || onx_die 2 "cert_path does not exist: ${CERT_PATH}"
  [[ -f "${KEY_PATH}" ]]  || onx_die 2 "key_path does not exist: ${KEY_PATH}"
fi

VHOST_PATH="${VHOST_DIR}/${USERNAME}-${DOMAIN}.conf"
BACKUP_PATH="${VHOST_PATH}.bak.$$"
[[ -f "${VHOST_PATH}" ]] && cp "${VHOST_PATH}" "${BACKUP_PATH}"

# v77.15: System subdomain branch — webmail/mail/panel/webdisk/autoconfig/autodiscover
# için template SKIP, doğrudan server block heredoc ile üretilir.
# (Caddy v82.1 ve OLS v79.2 pattern paralel.)
if [[ "${IS_SYSTEM_SUBDOMAIN}" == "true" ]]; then
  # Parent domain auto-detect (input'tan gelmezse DOMAIN'in ilk segmentini soy)
  if [[ -z "${PARENT_DOMAIN}" ]]; then
    PARENT_DOMAIN="${DOMAIN#*.}"
  fi

  # Cert lookup PARENT_DOMAIN üzerinden (multi-SAN cert tüm 7 hostname'i kapsar)
  # Caddy/OLS ile aynı 5-source lookup pattern.
  SYS_SSL=""
  SYS_CERT=""
  SYS_KEY=""
  if [[ -n "${CERT_PATH}" && -f "${CERT_PATH}" && -n "${KEY_PATH}" && -f "${KEY_PATH}" ]]; then
    SYS_CERT="${CERT_PATH}"
    SYS_KEY="${KEY_PATH}"
    SYS_SSL="true"
  elif [[ -f "/root/.acme.sh/${PARENT_DOMAIN}_ecc/fullchain.cer" && -f "/root/.acme.sh/${PARENT_DOMAIN}_ecc/${PARENT_DOMAIN}.key" ]]; then
    SYS_CERT="/root/.acme.sh/${PARENT_DOMAIN}_ecc/fullchain.cer"
    SYS_KEY="/root/.acme.sh/${PARENT_DOMAIN}_ecc/${PARENT_DOMAIN}.key"
    SYS_SSL="true"
  elif [[ -f "/root/.acme.sh/${PARENT_DOMAIN}/fullchain.cer" && -f "/root/.acme.sh/${PARENT_DOMAIN}/${PARENT_DOMAIN}.key" ]]; then
    SYS_CERT="/root/.acme.sh/${PARENT_DOMAIN}/fullchain.cer"
    SYS_KEY="/root/.acme.sh/${PARENT_DOMAIN}/${PARENT_DOMAIN}.key"
    SYS_SSL="true"
  elif [[ -f "/etc/letsencrypt/live/${PARENT_DOMAIN}/fullchain.pem" && -f "/etc/letsencrypt/live/${PARENT_DOMAIN}/privkey.pem" ]]; then
    SYS_CERT="/etc/letsencrypt/live/${PARENT_DOMAIN}/fullchain.pem"
    SYS_KEY="/etc/letsencrypt/live/${PARENT_DOMAIN}/privkey.pem"
    SYS_SSL="true"
  elif [[ -f "/usr/local/onoxsoft/ssl/${PARENT_DOMAIN}/fullchain.pem" && -f "/usr/local/onoxsoft/ssl/${PARENT_DOMAIN}/privkey.pem" ]]; then
    SYS_CERT="/usr/local/onoxsoft/ssl/${PARENT_DOMAIN}/fullchain.pem"
    SYS_KEY="/usr/local/onoxsoft/ssl/${PARENT_DOMAIN}/privkey.pem"
    SYS_SSL="true"
  fi

  # Log dizini (müşteri logs/ ile karışmasın — sistem subdomain SHARED log)
  mkdir -p /var/log/onoxsoft-system 2>/dev/null
  chmod 755 /var/log/onoxsoft-system 2>/dev/null

  # SSL aktif/değil-aktif ortak server block parçaları
  if [[ "${SYS_SSL}" == "true" ]]; then
    SYS_LISTEN_443=$(cat <<EOF
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ssl_certificate     ${SYS_CERT};
    ssl_certificate_key ${SYS_KEY};
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
EOF
)
    SYS_PORT80_REDIRECT="return 301 https://\$host\$request_uri;"
  else
    SYS_LISTEN_443=""
    SYS_PORT80_REDIRECT=""
  fi

  TMP_SYS_CONF=$(mktemp /tmp/onx-vhost-nginx-sys-XXXXXX.conf)
  trap 'rm -f "${TMP_SYS_CONF}"' EXIT

  case "${SUBDOMAIN_TYPE}" in
    webmail_proxy)
      # mail.<domain>, webmail.<domain> → Roundcube /usr/share/roundcubemail
      # PHP handler: panel pool socket (open_basedir Roundcube path'ine izinli)
      cat > "${TMP_SYS_CONF}" <<EOF
# Auto-generated by onx-vhost-add-nginx (subdomain_type=webmail_proxy)
# Parent: ${PARENT_DOMAIN} — v77.15 system subdomain
server {
    listen 80;
    listen [::]:80;
    server_name ${DOMAIN};

    access_log /var/log/onoxsoft-system/${DOMAIN}-access.log;
    error_log  /var/log/onoxsoft-system/${DOMAIN}-error.log;

    location ^~ /.well-known/acme-challenge/ {
        root /var/lib/letsencrypt;
        default_type "text/plain";
        try_files \$uri =404;
    }

EOF
      if [[ "${SYS_SSL}" == "true" ]]; then
        cat >> "${TMP_SYS_CONF}" <<EOF
    location / { ${SYS_PORT80_REDIRECT} }
}

server {
${SYS_LISTEN_443}
    server_name ${DOMAIN};
    root ${ROUNDCUBE_PATH};
    index index.php index.html;

    access_log /var/log/onoxsoft-system/${DOMAIN}-ssl-access.log;
    error_log  /var/log/onoxsoft-system/${DOMAIN}-ssl-error.log;

    # Roundcube sensitive dir/file leak prevention
    location ~ ^/(config|logs|SQL|vendor|bin|CHANGELOG|INSTALL|LICENSE|README|composer\\.) {
        deny all;
        return 403;
    }

    location / {
        try_files \$uri \$uri/ /index.php?\$query_string;
    }

    location ~ \\.php\$ {
        fastcgi_pass unix:${PANEL_FPM_SOCK};
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_read_timeout 60s;
    }

    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
}
EOF
      else
        # SSL yok — HTTP-only Roundcube serve
        cat >> "${TMP_SYS_CONF}" <<EOF
    root ${ROUNDCUBE_PATH};
    index index.php index.html;

    location ~ ^/(config|logs|SQL|vendor|bin|CHANGELOG|INSTALL|LICENSE|README|composer\\.) {
        deny all;
        return 403;
    }

    location / {
        try_files \$uri \$uri/ /index.php?\$query_string;
    }

    location ~ \\.php\$ {
        fastcgi_pass unix:${PANEL_FPM_SOCK};
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
        include fastcgi_params;
    }

    add_header X-Content-Type-Options "nosniff" always;
}
EOF
      fi
      ;;

    panel_redirect)
      # panel.<domain> → ONOXSOFT panel admin URL'sine 302 redirect
      _redir_target="${REDIRECT_TO:-https://panel.onoxsoft.com.tr:666/customer/dashboard}"
      cat > "${TMP_SYS_CONF}" <<EOF
# Auto-generated by onx-vhost-add-nginx (subdomain_type=panel_redirect)
# Parent: ${PARENT_DOMAIN} — v77.15 system subdomain
server {
    listen 80;
    listen [::]:80;
    server_name ${DOMAIN};

    access_log /var/log/onoxsoft-system/${DOMAIN}-access.log;

    location ^~ /.well-known/acme-challenge/ {
        root /var/lib/letsencrypt;
        default_type "text/plain";
        try_files \$uri =404;
    }

    location / {
        return 302 ${_redir_target}\$request_uri;
    }
}
EOF
      if [[ "${SYS_SSL}" == "true" ]]; then
        cat >> "${TMP_SYS_CONF}" <<EOF

server {
${SYS_LISTEN_443}
    server_name ${DOMAIN};

    access_log /var/log/onoxsoft-system/${DOMAIN}-ssl-access.log;

    location / {
        return 302 ${_redir_target}\$request_uri;
    }
}
EOF
      fi
      ;;

    webdisk)
      # webdisk.<domain> → Nginx native WebDAV (dav_methods) — basic auth
      # NOT: Nginx ngx_http_dav_module standart paket'te VAR (RHEL nginx),
      # ama PROPFIND/COPY için nginx-dav-ext-module gerekir. Yoksa redirect fallback.
      _webdisk_url="${REDIRECT_TO:-https://panel.onoxsoft.com.tr:666/customer/files}"
      cat > "${TMP_SYS_CONF}" <<EOF
# Auto-generated by onx-vhost-add-nginx (subdomain_type=webdisk)
# Parent: ${PARENT_DOMAIN} — v77.15 system subdomain
# NOT: Nginx native WebDAV PROPFIND için nginx-dav-ext-module gerekir.
# Yoksa panel files UI'sine 302 redirect (fallback).
server {
    listen 80;
    listen [::]:80;
    server_name ${DOMAIN};

    access_log /var/log/onoxsoft-system/${DOMAIN}-access.log;

    location ^~ /.well-known/acme-challenge/ {
        root /var/lib/letsencrypt;
        default_type "text/plain";
        try_files \$uri =404;
    }

    location / {
        return 302 ${_webdisk_url};
    }
}
EOF
      if [[ "${SYS_SSL}" == "true" ]]; then
        cat >> "${TMP_SYS_CONF}" <<EOF

server {
${SYS_LISTEN_443}
    server_name ${DOMAIN};

    access_log /var/log/onoxsoft-system/${DOMAIN}-ssl-access.log;

    location / {
        return 302 ${_webdisk_url};
    }
}
EOF
      fi
      ;;

    mail_autoconfig)
      # autodiscover.<domain> (Outlook) + autoconfig.<domain> (Thunderbird)
      # PHP handler: panel pool (autodiscover script /usr/local/onoxsoft/autodiscover)
      cat > "${TMP_SYS_CONF}" <<EOF
# Auto-generated by onx-vhost-add-nginx (subdomain_type=mail_autoconfig)
# Parent: ${PARENT_DOMAIN} — v77.15 system subdomain
server {
    listen 80;
    listen [::]:80;
    server_name ${DOMAIN};

    access_log /var/log/onoxsoft-system/${DOMAIN}-access.log;

    location ^~ /.well-known/acme-challenge/ {
        root /var/lib/letsencrypt;
        default_type "text/plain";
        try_files \$uri =404;
    }

EOF
      if [[ "${SYS_SSL}" == "true" ]]; then
        cat >> "${TMP_SYS_CONF}" <<EOF
    location / { ${SYS_PORT80_REDIRECT} }
}

server {
${SYS_LISTEN_443}
    server_name ${DOMAIN};
    root ${AUTODISCOVER_PATH};
    index index.php;

    access_log /var/log/onoxsoft-system/${DOMAIN}-ssl-access.log;

    # Outlook autodiscover (case-insensitive)
    location ~* ^/autodiscover/autodiscover\\.xml\$ {
        rewrite ^ /autodiscover.xml.php break;
        fastcgi_pass unix:${PANEL_FPM_SOCK};
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME \$document_root/autodiscover.xml.php;
        include fastcgi_params;
    }

    # Thunderbird / iOS Mail / Mozilla autoconfig
    location ~ ^/(mail/config-v1\\.1\\.xml|\\.well-known/autoconfig/mail/config-v1\\.1\\.xml)\$ {
        rewrite ^ /thunderbird.xml.php break;
        fastcgi_pass unix:${PANEL_FPM_SOCK};
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME \$document_root/thunderbird.xml.php;
        include fastcgi_params;
    }

    location ~ \\.php\$ {
        fastcgi_pass unix:${PANEL_FPM_SOCK};
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
        include fastcgi_params;
    }

    add_header X-Content-Type-Options "nosniff" always;
}
EOF
      else
        # SSL yok — HTTP-only autodiscover serve
        cat >> "${TMP_SYS_CONF}" <<EOF
    root ${AUTODISCOVER_PATH};
    index index.php;

    location ~* ^/autodiscover/autodiscover\\.xml\$ {
        rewrite ^ /autodiscover.xml.php break;
        fastcgi_pass unix:${PANEL_FPM_SOCK};
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME \$document_root/autodiscover.xml.php;
        include fastcgi_params;
    }

    location ~ ^/(mail/config-v1\\.1\\.xml|\\.well-known/autoconfig/mail/config-v1\\.1\\.xml)\$ {
        rewrite ^ /thunderbird.xml.php break;
        fastcgi_pass unix:${PANEL_FPM_SOCK};
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME \$document_root/thunderbird.xml.php;
        include fastcgi_params;
    }

    location ~ \\.php\$ {
        fastcgi_pass unix:${PANEL_FPM_SOCK};
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
        include fastcgi_params;
    }
}
EOF
      fi
      ;;

    *)
      onx_die 1 "unknown subdomain_type: ${SUBDOMAIN_TYPE} (expected: webmail_proxy|panel_redirect|webdisk|mail_autoconfig)"
      ;;
  esac

  # Install rendered config
  install -m 0644 "${TMP_SYS_CONF}" "${VHOST_PATH}"

  # ── nginx -t → rollback on failure ────────────────────────────────────────
  # System subdomain syntax hatası diğer 10+ vhost'u down eder, validate ŞART.
  # SKIP_RELOAD=true ise bulk mode (caller toplu test eder) → skip.
  if [[ "${SKIP_RELOAD}" != "true" ]]; then
    if ! timeout 10 nginx -t 2>/dev/null; then
      onx_log "nginx -t failed (system subdomain ${SUBDOMAIN_TYPE}) — rolling back"
      if [[ -f "${BACKUP_PATH}" ]]; then
        mv "${BACKUP_PATH}" "${VHOST_PATH}"
      else
        rm -f "${VHOST_PATH}"
      fi
      onx_die 4 "nginx -t failed; system subdomain rolled back"
    fi
  fi

  rm -f "${BACKUP_PATH}"

  # ── Reload nginx (graceful, v77.12 Caddy pattern paralel) ─────────────────
  RELOADED="false"
  if [[ "${SKIP_RELOAD}" == "true" ]]; then
    RELOADED="skipped_bulk"
  elif systemctl is-active --quiet nginx; then
    if timeout 15 systemctl reload nginx 2>/dev/null; then
      RELOADED="true"
    else
      RELOADED="reload_failed"
      onx_log "nginx aktif ama reload failed (system subdomain)"
    fi
  else
    RELOADED="deferred"
    onx_log "nginx down — system subdomain vhost yazıldı, start'ta yüklenecek"
  fi

  onx_json_out \
    "vhost_path"           "${VHOST_PATH}" \
    "reloaded"             "${RELOADED}" \
    "ssl_enabled"          "${SYS_SSL:-false}" \
    "server"               "nginx" \
    "is_system_subdomain"  "true" \
    "subdomain_type"       "${SUBDOMAIN_TYPE}" \
    "parent_domain"        "${PARENT_DOMAIN}"
  exit 0
fi

# ── Build server aliases (space-separated for Nginx) ─────────────────────────
SERVER_ALIASES=""
while IFS= read -r alias; do
  [[ -n "${alias}" ]] && SERVER_ALIASES+="${alias} "
done < <(onx_json_array_items "${INPUT}" "server_aliases")
SERVER_ALIASES="${SERVER_ALIASES% }"

# ── Build HTTPS server block ─────────────────────────────────────────────────
if [[ "${SSL_ENABLED}" == "true" ]]; then
  HTTPS_TEMPLATE="${TEMPLATE_HTTPS_PATH}"
  if [[ "${REVERSE_PROXY}" == "true" ]]; then
    HTTPS_TEMPLATE="${TEMPLATE_RP_HTTPS_PATH}"
  fi
  [[ -f "${HTTPS_TEMPLATE}" ]] || onx_die 2 "https template not found: ${HTTPS_TEMPLATE}"
  HTTPS_VHOST_BLOCK=$(cat "${HTTPS_TEMPLATE}")
else
  HTTPS_VHOST_BLOCK=""
fi

# ── Build HTTP server body ───────────────────────────────────────────────────
# v73.4: SSL açıkken HTTP server'da YALNIZ 301 redirect olur (statik location'lar
# ve fastcgi/proxy blokları HTTPS server bloğuna geçer). Yoksa "duplicate
# location /" yapısal hatası çıkar (eski ${HTTPS_REDIRECT_BLOCK} + statik
# location / üst üste). SSL kapalıyken full body HTTP'de kalır.
if [[ "${SSL_ENABLED}" == "true" ]]; then
  HTTP_BODY_BLOCK=$(cat <<'BLOCK'
    # SSL aktif — port 80 yalnızca HTTPS redirect
    location / {
        return 301 https://$host$request_uri;
    }
BLOCK
)
else
  # SSL yok — full PHP-FPM / static / security HTTP'de
  if [[ "${REVERSE_PROXY}" == "true" ]]; then
    HTTP_BODY_BLOCK=$(cat <<'BLOCK'
    # Static dosyalar Nginx serve eder (Apache'ye gitmesin)
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2?|svg|webp|avif|pdf|zip|tar\.gz|mp4|webm)$ {
        root ${DOC_ROOT};
        expires 30d;
        access_log off;
        add_header Cache-Control "public, immutable";
        try_files $uri @apache_backend;
    }

    location @apache_backend {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
    }

    # Dynamic istekler → Apache
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_read_timeout 60s;
        proxy_connect_timeout 10s;
        proxy_buffering on;
        proxy_buffers 16 16k;
        proxy_buffer_size 32k;
    }

    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss image/svg+xml;

    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
BLOCK
)
  else
    HTTP_BODY_BLOCK=$(cat <<'BLOCK'
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/opt/remi/php${PHP_VERSION_NODOT}/run/php-fpm/${USERNAME}.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_read_timeout 60s;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
    }

    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;

    location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2?|svg|webp|avif)$ {
        expires 30d;
        access_log off;
        add_header Cache-Control "public, immutable";
    }

    location ~ /\.(?!well-known) {
        deny all;
        access_log off;
        log_not_found off;
    }
BLOCK
)
  fi
fi

# ── Render template ──────────────────────────────────────────────────────────
# v73: awk multiline_replace KALDIRILDI (CPU infinite loop bug). envsubst pattern.
# envsubst sadece export edilen değişkenleri tanır + multi-line val SAFE
# (shell variable expansion, awk substring search değil).
TMP_CONF=$(mktemp /tmp/onx-vhost-nginx-XXXXXX.conf)
trap 'rm -f "${TMP_CONF}"' EXIT

# Reverse-proxy modunda HTTPS_VHOST_BLOCK_REVERSE_PROXY placeholder kullanılır,
# normal modda HTTPS_VHOST_BLOCK. Önce uygun değişkene set, sonra her ikisini de export.
if [[ "${REVERSE_PROXY}" == "true" ]]; then
    HTTPS_VHOST_BLOCK_REVERSE_PROXY="${HTTPS_VHOST_BLOCK}"
    HTTPS_VHOST_BLOCK=""
    SOURCE_TEMPLATE="${TEMPLATE_RP_PATH}"
else
    HTTPS_VHOST_BLOCK_REVERSE_PROXY=""
    SOURCE_TEMPLATE="${TEMPLATE_PATH}"
fi

# Export — envsubst sadece exported vars'ı görür
export USERNAME DOMAIN DOC_ROOT PHP_VERSION PHP_VERSION_NODOT SERVER_ALIASES
export HTTP_BODY_BLOCK HTTPS_VHOST_BLOCK HTTPS_VHOST_BLOCK_REVERSE_PROXY
export CERT_PATH KEY_PATH

# envsubst: SADECE listede yer alan değişkenleri replace et (Nginx config'inde
# $uri, $host gibi NGINX VARIABLE'ları korunsun — onlar export EDILMEDI, dokunmayacak).
# v73.4: HTTPS_REDIRECT_BLOCK ELİMİNE — HTTP_BODY_BLOCK içine entegre edildi.
ENVSUBST_VARS='${USERNAME} ${DOMAIN} ${DOC_ROOT} ${PHP_VERSION} ${PHP_VERSION_NODOT} ${SERVER_ALIASES} ${HTTP_BODY_BLOCK} ${HTTPS_VHOST_BLOCK} ${HTTPS_VHOST_BLOCK_REVERSE_PROXY} ${CERT_PATH} ${KEY_PATH}'

# v73.3: TWO-PASS envsubst.
# 1. pass: ${HTTPS_VHOST_BLOCK}, ${HTTPS_REDIRECT_BLOCK} gibi multi-line bloklar inject edilir.
# 2. pass: inject edilen blok içindeki ${USERNAME}, ${PHP_VERSION_NODOT} gibi NESTED
#          placeholder'lar substitute olur (envsubst replaced-content'i tekrar process etmez).
TMP_CONF_PASS1=$(mktemp /tmp/onx-vhost-nginx-pass1-XXXXXX.conf)
trap 'rm -f "${TMP_CONF}" "${TMP_CONF_PASS1}"' EXIT

if ! envsubst "${ENVSUBST_VARS}" < "${SOURCE_TEMPLATE}" > "${TMP_CONF_PASS1}"; then
    onx_die 3 "envsubst template render failed (pass1)"
fi

if ! envsubst "${ENVSUBST_VARS}" < "${TMP_CONF_PASS1}" > "${TMP_CONF}"; then
    onx_die 3 "envsubst template render failed (pass2)"
fi

# Install the rendered config
install -m 0644 "${TMP_CONF}" "${VHOST_PATH}"

# ── nginx -t → rollback on failure ───────────────────────────────────────────
# v73.1: bulk modda nginx -t SKIP (O(N²) sorunu — her vhost-add tüm conf'ları
# parse eder, 2000 domain × 2000 = 4M iterasyon). Caller bulk sonunda nginx -t çağırır.
if [[ "${SKIP_RELOAD}" != "true" ]]; then
    if ! timeout 10 nginx -t 2>/dev/null; then
        onx_log "nginx -t failed — rolling back"
        if [[ -f "${BACKUP_PATH}" ]]; then
            mv "${BACKUP_PATH}" "${VHOST_PATH}"
        else
            rm -f "${VHOST_PATH}"
        fi
        onx_die 4 "nginx -t failed; vhost rolled back"
    fi
fi

rm -f "${BACKUP_PATH}"

# ── Reload nginx ─────────────────────────────────────────────────────────────
# v72.2: Nginx down ise reload skip; v72.3: bulk mode'da reload skip
RELOADED="false"
if [[ "${SKIP_RELOAD}" == "true" ]]; then
    # Bulk migration — caller sonunda tek seferde reload eder
    RELOADED="skipped_bulk"
elif systemctl is-active --quiet nginx; then
    if timeout 15 systemctl reload nginx 2>/dev/null; then
        RELOADED="true"
    else
        onx_die 3 "systemctl reload nginx failed (timeout/error)"
    fi
else
    RELOADED="deferred"
fi

# ── Success ──────────────────────────────────────────────────────────────────
onx_json_out \
  "vhost_path"    "${VHOST_PATH}" \
  "reloaded"      "${RELOADED}" \
  "ssl_enabled"   "${SSL_ENABLED}" \
  "server"        "nginx" \
  "reverse_proxy" "${REVERSE_PROXY}"
