#!/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"

# ── 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")

# ── Input validation ─────────────────────────────────────────────────────────
onx_validate_username "${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"

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 "/home/${USERNAME}" ]] || onx_die 2 "home directory not found: /home/${USERNAME}"

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

mkdir -p "/home/${USERNAME}/logs"

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

# ── 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% }"

# ── HTTPS redirect block (port 80 → 443) ─────────────────────────────────────
if [[ "${SSL_ENABLED}" == "true" ]]; then
  HTTPS_REDIRECT_BLOCK=$(cat <<'BLOCK'
    # Redirect HTTP to HTTPS (except ACME challenge)
    location / {
        return 301 https://$host$request_uri;
    }
BLOCK
)
else
  HTTPS_REDIRECT_BLOCK=""
fi

# ── 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

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

if [[ "${REVERSE_PROXY}" == "true" ]]; then
  cp "${TEMPLATE_RP_PATH}" "${TMP_CONF}"
else
  cp "${TEMPLATE_PATH}" "${TMP_CONF}"
fi

sed_replace() {
  local var="$1" val="$2"
  local escaped_val
  escaped_val=$(printf '%s' "${val}" | sed 's/[&\\/]/\\&/g')
  # Use python for multi-line value replacement (sed has issues with multi-line)
  python3 -c "
import sys
with open('${TMP_CONF}', 'r') as f:
    content = f.read()
content = content.replace('\${${var}}', '''${escaped_val}''')
with open('${TMP_CONF}', 'w') as f:
    f.write(content)
" 2>/dev/null || {
    # Fallback: single-line replacement via sed (won't handle multi-line vars)
    sed -i "s|\${${var}}|${escaped_val}|g" "${TMP_CONF}" 2>/dev/null || true
  }
}

# Multi-line capable replacement via awk
multiline_replace() {
  local var="$1"
  local val="$2"
  local tmpfile="${TMP_CONF}.replace"
  awk -v var="\${${var}}" -v val="${val}" '
    {
      while ((idx = index($0, var)) > 0) {
        $0 = substr($0, 1, idx-1) val substr($0, idx + length(var))
      }
      print
    }
  ' "${TMP_CONF}" > "${tmpfile}"
  mv "${tmpfile}" "${TMP_CONF}"
}

multiline_replace "USERNAME"            "${USERNAME}"
multiline_replace "DOMAIN"              "${DOMAIN}"
multiline_replace "DOC_ROOT"            "${DOC_ROOT}"
multiline_replace "PHP_VERSION_NODOT"   "${PHP_VERSION_NODOT}"
multiline_replace "SERVER_ALIASES"      "${SERVER_ALIASES}"
multiline_replace "HTTPS_REDIRECT_BLOCK" "${HTTPS_REDIRECT_BLOCK}"

if [[ "${REVERSE_PROXY}" == "true" ]]; then
  multiline_replace "HTTPS_VHOST_BLOCK_REVERSE_PROXY" "${HTTPS_VHOST_BLOCK}"
else
  multiline_replace "HTTPS_VHOST_BLOCK" "${HTTPS_VHOST_BLOCK}"
fi

multiline_replace "CERT_PATH" "${CERT_PATH}"
multiline_replace "KEY_PATH"  "${KEY_PATH}"

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

# ── nginx -t → rollback on failure ───────────────────────────────────────────
if ! 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

rm -f "${BACKUP_PATH}"

# ── Reload nginx ─────────────────────────────────────────────────────────────
if ! systemctl reload nginx; then
  onx_die 3 "systemctl reload nginx failed"
fi

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