#!/usr/bin/env bash
# onx-fpm-pool-create — Create a per-user PHP-FPM pool config.
#
# Input (stdin JSON):
#   username      string  Linux username (onx_xxx)
#   php_version   string  "8.1", "8.2", "8.3", etc.
#   memory_limit  string  PHP memory_limit value (default: "256M")
#   max_children  int     pm.max_children (default: 10)
#
# Output (stdout JSON):
#   {"pool":..., "socket":..., "version":..., "config_path":...}
#
# 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-create

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/fpm-pool.conf.stub"

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

onx_require_json "${INPUT}"

USERNAME=$(onx_json_get "${INPUT}" "username")
PHP_VERSION=$(onx_json_get "${INPUT}" "php_version")
MEMORY_LIMIT=$(onx_json_get "${INPUT}" "memory_limit" "256M")
MAX_CHILDREN=$(onx_json_get "${INPUT}" "max_children" "10")

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

[[ -z "${PHP_VERSION}" ]] && onx_die 1 "php_version is required"
[[ "${PHP_VERSION}" =~ ^[0-9]\.[0-9]$ ]] || onx_die 1 "php_version must be x.y format, got: ${PHP_VERSION}"
[[ "${MAX_CHILDREN}" =~ ^[0-9]+$ ]]       || onx_die 1 "max_children must be a positive integer"
[[ "${MEMORY_LIMIT}" =~ ^[0-9]+[MmGg]$ ]] || onx_die 1 "memory_limit must be like 256M or 1G"

# php_version "8.2" → "82"
PHP_VERSION_NODOT="${PHP_VERSION//./}"

# Pool config path and socket path use remi-php convention
POOL_DIR="/etc/opt/remi/php${PHP_VERSION_NODOT}/php-fpm.d"
POOL_PATH="${POOL_DIR}/${USERNAME}.conf"
SOCKET_PATH="/var/opt/remi/php${PHP_VERSION_NODOT}/run/php-fpm/${USERNAME}.sock"
FPM_SERVICE="php${PHP_VERSION_NODOT}-php-fpm"

# ── Preflight ────────────────────────────────────────────────────────────────
[[ -f "${TEMPLATE_PATH}" ]] || onx_die 2 "fpm pool template not found: ${TEMPLATE_PATH}"
[[ -d "${POOL_DIR}" ]]      || onx_die 2 "FPM pool dir not found: ${POOL_DIR} (is php${PHP_VERSION_NODOT} installed?)"
[[ -d "/home/${USERNAME}" ]] || onx_die 2 "home directory not found: /home/${USERNAME}"
command -v systemctl >/dev/null 2>&1 || onx_die 2 "systemctl not found"

# ── Ensure user tmp dir exists ───────────────────────────────────────────────
mkdir -p "/home/${USERNAME}/tmp" "/home/${USERNAME}/logs"
chown "${USERNAME}:${USERNAME}" "/home/${USERNAME}/tmp" "/home/${USERNAME}/logs"

# ── Back up existing pool (if any) ───────────────────────────────────────────
BACKUP_PATH="${POOL_PATH}.bak.$$"
[[ -f "${POOL_PATH}" ]] && cp "${POOL_PATH}" "${BACKUP_PATH}"

# ── Render template ──────────────────────────────────────────────────────────
TMP_CONF=$(mktemp /tmp/onx-fpm-XXXXXX.conf)
trap 'rm -f "${TMP_CONF}"' EXIT

cp "${TEMPLATE_PATH}" "${TMP_CONF}"

sed_replace() {
  local var="$1" val="$2"
  local escaped_val
  escaped_val=$(printf '%s' "${val}" | sed 's/[&\\/]/\\&/g; s/$/\\n/' | tr -d '\n' | sed 's/\\n$//')
  sed -i "s|\${${var}}|${escaped_val}|g" "${TMP_CONF}"
}

sed_replace "USERNAME"          "${USERNAME}"
sed_replace "PHP_VERSION"       "${PHP_VERSION}"
sed_replace "PHP_VERSION_NODOT" "${PHP_VERSION_NODOT}"
sed_replace "MEMORY_LIMIT"      "${MEMORY_LIMIT}"
sed_replace "MAX_CHILDREN"      "${MAX_CHILDREN}"

install -m 0640 "${TMP_CONF}" "${POOL_PATH}"

# ── Reload FPM ───────────────────────────────────────────────────────────────
if ! systemctl reload "${FPM_SERVICE}" 2>/dev/null; then
  onx_log "reload failed — trying restart for ${FPM_SERVICE}"
  if ! systemctl restart "${FPM_SERVICE}"; then
    # Rollback
    if [[ -f "${BACKUP_PATH}" ]]; then
      mv "${BACKUP_PATH}" "${POOL_PATH}"
    else
      rm -f "${POOL_PATH}"
    fi
    onx_die 4 "FPM service ${FPM_SERVICE} failed to reload/restart; config rolled back"
  fi
fi

rm -f "${BACKUP_PATH}"

# ── Verify socket created ────────────────────────────────────────────────────
# Give FPM up to 5 seconds to create the socket
WAITED=0
while [[ ! -S "${SOCKET_PATH}" && "${WAITED}" -lt 5 ]]; do
  sleep 1
  WAITED=$(( WAITED + 1 ))
done

SOCKET_PRESENT="false"
[[ -S "${SOCKET_PATH}" ]] && SOCKET_PRESENT="true"

# ── Success ──────────────────────────────────────────────────────────────────
onx_json_out \
  "pool"          "${USERNAME}" \
  "socket"        "${SOCKET_PATH}" \
  "socket_exists" "${SOCKET_PRESENT}" \
  "version"       "${PHP_VERSION}" \
  "config_path"   "${POOL_PATH}"
