#!/usr/bin/env bash
# onx-fpm-pool-tune — Mevcut FPM pool dosyasının ayarlarını tune et.
#
# v3.22: Controller parameter names ile uyumlu
#
# Input (stdin JSON) — Controller'dan gelen format:
#   {
#     "username":           "onx_acme01",   // pool_name yerine
#     "php_version":        "8.2",
#     "pm_mode":            "ondemand|dynamic|static",
#     "max_children":       10,
#     "start_servers":      2,
#     "min_spare_servers":  1,
#     "max_spare_servers":  3,
#     "max_requests":       500,
#     "process_idle_timeout":       "10s",
#     "request_terminate_timeout":  "60s",
#     "memory_limit":       "256M",
#     "custom_directives":  []  // optional
#   }
#
# Output: {"pool":"...", "version":"...", "reloaded":true}

set -euo pipefail

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

require_root
onx_json_input

# v3.22: Hem username hem pool_name kabul et (backward compat)
USERNAME="$(onx_json_field username)"
if [[ -z "$USERNAME" ]]; then
    USERNAME="$(onx_json_field pool_name)"
fi
PHP_VERSION="$(onx_json_field php_version)"
PM_MODE="$(onx_json_field pm_mode 'ondemand')"
PM_MAX_CHILDREN="$(onx_json_field max_children '10')"
PM_START_SERVERS="$(onx_json_field start_servers '2')"
PM_MIN_SPARE="$(onx_json_field min_spare_servers '1')"
PM_MAX_SPARE="$(onx_json_field max_spare_servers '3')"
PM_MAX_REQUESTS="$(onx_json_field max_requests '500')"
PM_IDLE_TIMEOUT="$(onx_json_field process_idle_timeout '10s')"
REQUEST_TIMEOUT="$(onx_json_field request_terminate_timeout '60s')"
MEMORY_LIMIT="$(onx_json_field memory_limit '256M')"

# Validation
[[ -z "$USERNAME" ]]    && onx_die 1 "username (veya pool_name) zorunlu"
[[ -z "$PHP_VERSION" ]] && onx_die 1 "php_version zorunlu"
[[ "$USERNAME"    =~ ^[a-z0-9_-]+$ ]] || onx_die 1 "Gecersiz username"
[[ "$PHP_VERSION" =~ ^[7-9]\.[0-9]+$ ]] || onx_die 1 "Gecersiz php_version (x.y)"
[[ "$PM_MODE" =~ ^(ondemand|dynamic|static)$ ]] || onx_die 1 "pm_mode: ondemand|dynamic|static"
[[ "$PM_MAX_CHILDREN" =~ ^[0-9]+$ ]] || onx_die 1 "max_children sayi"
[[ "$PM_MAX_CHILDREN" -ge 1 && "$PM_MAX_CHILDREN" -le 500 ]] || onx_die 1 "max_children 1-500"

VERSION_NODOT="${PHP_VERSION//./}"
POOL_DIR="/etc/opt/remi/php${VERSION_NODOT}/php-fpm.d"
POOL_FILE="${POOL_DIR}/${USERNAME}.conf"
FPM_UNIT="php${VERSION_NODOT}-php-fpm"

# Pool dosyasi yoksa fpm-pool-create yapmaliyiz, tune edemeyiz
if [[ ! -f "$POOL_FILE" ]]; then
    # Alternative naming: onx_USERNAME.conf, onoxsoft-USERNAME.conf
    for alt in "${POOL_DIR}/onx_${USERNAME}.conf" "${POOL_DIR}/onoxsoft-${USERNAME}.conf"; do
        if [[ -f "$alt" ]]; then
            POOL_FILE="$alt"
            break
        fi
    done
fi
[[ -f "$POOL_FILE" ]] || onx_die 2 "Pool dosyasi yok: $POOL_FILE — once fpm-pool-create"

onx_log "fpm-pool-tune: user=${USERNAME} php=${PHP_VERSION} pm=${PM_MODE} max=${PM_MAX_CHILDREN} file=${POOL_FILE}"

# Backup
cp -a "$POOL_FILE" "${POOL_FILE}.bak-$(date +%Y%m%d%H%M%S)"

# Idempotent in-place edit — sadece KEY=VALUE replace, eksikse append
update_directive() {
    local key="$1" val="$2"
    # Regex-safe escape for sed (slash + ampersand)
    local val_escaped
    val_escaped=$(printf '%s' "$val" | sed 's/[&/\\]/\\&/g')
    if grep -qE "^[[:space:]]*${key}[[:space:]]*=" "$POOL_FILE"; then
        sed -i -E "s|^[[:space:]]*${key}[[:space:]]*=.*|${key} = ${val_escaped}|" "$POOL_FILE"
    else
        echo "${key} = ${val}" >> "$POOL_FILE"
    fi
}

update_directive "pm" "${PM_MODE}"
update_directive "pm.max_children" "${PM_MAX_CHILDREN}"
update_directive "pm.max_requests" "${PM_MAX_REQUESTS}"

case "${PM_MODE}" in
    dynamic)
        update_directive "pm.start_servers" "${PM_START_SERVERS}"
        update_directive "pm.min_spare_servers" "${PM_MIN_SPARE}"
        update_directive "pm.max_spare_servers" "${PM_MAX_SPARE}"
        ;;
    ondemand)
        update_directive "pm.process_idle_timeout" "${PM_IDLE_TIMEOUT}"
        ;;
esac

update_directive "request_terminate_timeout" "${REQUEST_TIMEOUT}"

# PHP per-pool ini directives (php_admin_value[])
phpini_directive() {
    local key="$1" val="$2"
    local val_escaped
    val_escaped=$(printf '%s' "$val" | sed 's/[&/\\]/\\&/g')
    local line="php_admin_value[${key}] = ${val_escaped}"
    if grep -qE "^[[:space:]]*php_admin_value\[${key}\][[:space:]]*=" "$POOL_FILE"; then
        sed -i -E "s|^[[:space:]]*php_admin_value\[${key}\][[:space:]]*=.*|${line}|" "$POOL_FILE"
    else
        echo "php_admin_value[${key}] = ${val}" >> "$POOL_FILE"
    fi
}
phpini_directive "memory_limit" "${MEMORY_LIMIT}"

# Custom directives — Controller'dan array gelir, her birini ekle
CUSTOM_DIRECTIVES_JSON=$(echo "$INPUT" | jq -c '.custom_directives // []' 2>/dev/null || echo '[]')
if [[ "${CUSTOM_DIRECTIVES_JSON}" != "[]" ]] && [[ "${CUSTOM_DIRECTIVES_JSON}" != "null" ]]; then
    echo "$INPUT" | jq -r '.custom_directives[]? | "\(.key)|\(.value)"' 2>/dev/null | while IFS='|' read -r ckey cval; do
        [[ -z "$ckey" ]] && continue
        # Custom = php_value[] or php_flag[]
        if [[ "$cval" =~ ^(on|off)$ ]] 2>/dev/null; then
            echo "php_flag[${ckey}] = ${cval}" >> "$POOL_FILE"
        else
            echo "php_value[${ckey}] = ${cval}" >> "$POOL_FILE"
        fi
    done
fi

# Reload FPM
RELOADED="false"
if systemctl is-active --quiet "${FPM_UNIT}" 2>/dev/null; then
    if systemctl reload "${FPM_UNIT}" 2>/dev/null; then
        RELOADED="true"
    elif systemctl restart "${FPM_UNIT}" 2>/dev/null; then
        RELOADED="true"
    fi
fi

json_ok "{\"username\":\"${USERNAME}\",\"php_version\":\"${PHP_VERSION}\",\"pool_file\":\"${POOL_FILE}\",\"reloaded\":${RELOADED}}"
