#!/usr/bin/env bash
# onx-fpm-pool-switch-version — Move a user's FPM pool from one PHP version to another.
# Also updates the vhost's SetHandler line to point to the new socket.
#
# Input (stdin JSON):
#   username      string  Linux username (onx_xxx)
#   domain        string  Domain name (used to find vhost file)
#   old_version   string  Current PHP version ("8.1")
#   new_version   string  Target PHP version ("8.2")
#   vhost_file    string  vhost config filename (e.g. "onx_xxx-example.com.conf")
#
# Output (stdout JSON):
#   {"switched":true, "old_version":..., "new_version":..., "socket":...}
#
# Exit codes: 0=ok 1=invalid-input 2=preflight-fail 3=exec-fail 4=rolled-back
#
# Deployed to: /usr/local/onoxsoft/bin/onx-fpm-pool-switch-version

set -euo pipefail

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

VHOST_DIR="/etc/httpd/conf.d/sites"

# ── Read & parse stdin ───────────────────────────────────────────────────────
INPUT=$(cat)

onx_require_json "${INPUT}"

USERNAME=$(onx_json_get "${INPUT}" "username")
DOMAIN=$(onx_json_get "${INPUT}" "domain")
OLD_VERSION=$(onx_json_get "${INPUT}" "old_version")
NEW_VERSION=$(onx_json_get "${INPUT}" "new_version")
VHOST_FILE=$(onx_json_get "${INPUT}" "vhost_file" "")

# ── Input validation ─────────────────────────────────────────────────────────
onx_validate_username "${USERNAME}"
onx_validate_domain "${DOMAIN}"
[[ -z "${OLD_VERSION}" ]] && onx_die 1 "old_version is required"
[[ -z "${NEW_VERSION}" ]] && onx_die 1 "new_version is required"
[[ "${OLD_VERSION}" == "${NEW_VERSION}" ]] && onx_die 1 "old_version and new_version are the same"
[[ "${OLD_VERSION}" =~ ^[0-9]\.[0-9]$ ]] || onx_die 1 "old_version must be x.y format"
[[ "${NEW_VERSION}" =~ ^[0-9]\.[0-9]$ ]] || onx_die 1 "new_version must be x.y format"

OLD_NODOT="${OLD_VERSION//./}"
NEW_NODOT="${NEW_VERSION//./}"

OLD_POOL_PATH="/etc/opt/remi/php${OLD_NODOT}/php-fpm.d/${USERNAME}.conf"
NEW_POOL_DIR="/etc/opt/remi/php${NEW_NODOT}/php-fpm.d"
NEW_POOL_PATH="${NEW_POOL_DIR}/${USERNAME}.conf"
NEW_SOCKET="/var/opt/remi/php${NEW_NODOT}/run/php-fpm/${USERNAME}.sock"
NEW_FPM_SERVICE="php${NEW_NODOT}-php-fpm"
OLD_FPM_SERVICE="php${OLD_NODOT}-php-fpm"

# Vhost file path
if [[ -z "${VHOST_FILE}" ]]; then
  VHOST_FILE="${USERNAME}-${DOMAIN}.conf"
fi
VHOST_PATH="${VHOST_DIR}/${VHOST_FILE}"

# ── Preflight ────────────────────────────────────────────────────────────────
[[ -d "${NEW_POOL_DIR}" ]] || onx_die 2 "php${NEW_NODOT} pool dir not found: ${NEW_POOL_DIR}"
[[ -f "${VHOST_PATH}" ]]   || onx_die 2 "vhost file not found: ${VHOST_PATH}"
command -v apachectl  >/dev/null 2>&1 || onx_die 2 "apachectl not found"
command -v systemctl  >/dev/null 2>&1 || onx_die 2 "systemctl not found"

# ── Copy old pool config to new version (preserve settings) ─────────────────
if [[ -f "${OLD_POOL_PATH}" ]]; then
  # Copy and fix the listen path in the new pool
  cp "${OLD_POOL_PATH}" "${NEW_POOL_PATH}"
  sed -i "s|php${OLD_NODOT}/run/php-fpm|php${NEW_NODOT}/run/php-fpm|g" "${NEW_POOL_PATH}"
  onx_log "Copied pool config from php${OLD_NODOT} to php${NEW_NODOT}"
else
  # No old pool — call onx-fpm-pool-create for new version with defaults
  onx_log "Old pool config not found; will be created by FPM on next request"
  # Write minimal pool config
  cat > "${NEW_POOL_PATH}" <<POOL
[${USERNAME}]
user = ${USERNAME}
group = ${USERNAME}
listen = /var/opt/remi/php${NEW_NODOT}/run/php-fpm/${USERNAME}.sock
listen.owner = apache
listen.group = ${USERNAME}
listen.mode = 0660
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 30s
pm.max_requests = 500
php_admin_value[memory_limit] = 256M
php_admin_value[open_basedir] = /home/${USERNAME}:/tmp:/var/lib/php/session
php_admin_value[disable_functions] = exec,system,passthru,shell_exec,proc_open,popen
php_admin_value[date.timezone] = Europe/Istanbul
POOL
fi

# ── Update vhost SetHandler to new socket ───────────────────────────────────
VHOST_BACKUP="${VHOST_PATH}.bak.$$"
cp "${VHOST_PATH}" "${VHOST_BACKUP}"

sed -i "s|php${OLD_NODOT}/run/php-fpm/${USERNAME}.sock|php${NEW_NODOT}/run/php-fpm/${USERNAME}.sock|g" "${VHOST_PATH}"

# ── Reload new FPM ───────────────────────────────────────────────────────────
if ! systemctl reload "${NEW_FPM_SERVICE}" 2>/dev/null; then
  systemctl restart "${NEW_FPM_SERVICE}" || {
    # Rollback vhost
    mv "${VHOST_BACKUP}" "${VHOST_PATH}"
    rm -f "${NEW_POOL_PATH}"
    onx_die 4 "Failed to start ${NEW_FPM_SERVICE}; changes rolled back"
  }
fi

# ── Apache configtest + reload ───────────────────────────────────────────────
if ! apachectl configtest 2>/dev/null; then
  onx_log "configtest failed — rolling back vhost"
  mv "${VHOST_BACKUP}" "${VHOST_PATH}"
  rm -f "${NEW_POOL_PATH}"
  onx_die 4 "apachectl configtest failed; vhost rolled back"
fi
rm -f "${VHOST_BACKUP}"

systemctl reload httpd || onx_die 3 "systemctl reload httpd failed"

# ── Remove old pool config (optional, best-effort) ───────────────────────────
if [[ -f "${OLD_POOL_PATH}" ]]; then
  rm -f "${OLD_POOL_PATH}"
  systemctl reload "${OLD_FPM_SERVICE}" 2>/dev/null || true
fi

# ── Success ──────────────────────────────────────────────────────────────────
onx_json_out \
  "switched"    "true" \
  "old_version" "${OLD_VERSION}" \
  "new_version" "${NEW_VERSION}" \
  "socket"      "${NEW_SOCKET}"
