#!/usr/bin/env bash
# onx-vhost-add-ols — Create an OpenLiteSpeed vhost from template.
#
# Called by onx-vhost-add dispatcher when 'server' = 'openlitespeed' or 'litespeed'.
# OLS vhost config: /usr/local/lsws/conf/vhosts/<vh_name>/vhconf.conf
# listener.conf'a map entry de eklenmesi gerekir.
#
# Input (stdin JSON) — same as onx-vhost-add.
# Output (stdout JSON):
#   {"vhost_path":..., "reloaded":true, "ssl_enabled":..., "server":"openlitespeed"}
#
# 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-ols.conf.stub"
LSWS_BASE="/usr/local/lsws"
VHOST_BASE="${LSWS_BASE}/conf/vhosts"
LISTENER_CONF="${LSWS_BASE}/conf/httpd_config.conf"
LSWS_CTL="${LSWS_BASE}/bin/lswsctrl"

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

# ── 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 ────────────────────────────────────────────────────────────────
[[ -d "${LSWS_BASE}" ]] || onx_die 2 "OpenLiteSpeed not installed: ${LSWS_BASE} not found"
[[ -x "${LSWS_CTL}" ]] || onx_die 2 "lswsctrl not found: ${LSWS_CTL}"
[[ -f "${TEMPLATE_PATH}" ]] || onx_die 2 "ols template not found: ${TEMPLATE_PATH}"
[[ -d "/home/${USERNAME}" ]] || onx_die 2 "home directory not found: /home/${USERNAME}"

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

VH_NAME="${USERNAME}-${DOMAIN}"
VHOST_DIR="${VHOST_BASE}/${VH_NAME}"
VHOST_PATH="${VHOST_DIR}/vhconf.conf"
LISTENER_BACKUP="${LISTENER_CONF}.bak.$$"

mkdir -p "${VHOST_DIR}"
BACKUP_PATH="${VHOST_PATH}.bak.$$"
[[ -f "${VHOST_PATH}" ]] && cp "${VHOST_PATH}" "${BACKUP_PATH}"

# ── Build comma-separated aliases ────────────────────────────────────────────
SERVER_ALIASES_COMMA=""
while IFS= read -r alias; do
  [[ -n "${alias}" ]] && SERVER_ALIASES_COMMA+="${alias},"
done < <(onx_json_array_items "${INPUT}" "server_aliases")
SERVER_ALIASES_COMMA="${SERVER_ALIASES_COMMA%,}"

# ── Build SSL block ──────────────────────────────────────────────────────────
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"
  OLS_SSL_BLOCK=$(cat <<SSLBLOCK
vhssl {
  keyFile                 ${KEY_PATH}
  certFile                ${CERT_PATH}
  certChain               1
  sslProtocol             24
  enableECDHE             1
  renegProtection         1
  sslSessionCache         1
  enableSpdy              15
}
SSLBLOCK
)
else
  OLS_SSL_BLOCK=""
fi

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

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

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_COMMA" "${SERVER_ALIASES_COMMA}"
multiline_replace "OLS_SSL_BLOCK"        "${OLS_SSL_BLOCK}"

# Install the rendered config
install -m 0644 "${TMP_CONF}" "${VHOST_PATH}"
chown -R lsadm:lsadm "${VHOST_DIR}" 2>/dev/null || true

# ── Update listener.conf with vhost mapping ──────────────────────────────────
# Add vhost map: virtualhost <VH_NAME> {} and listener entries
if ! grep -q "virtualhost ${VH_NAME}" "${LISTENER_CONF}"; then
  cp "${LISTENER_CONF}" "${LISTENER_BACKUP}"
  cat >> "${LISTENER_CONF}" <<MAPEOF

virtualhost ${VH_NAME} {
  vhRoot                  ${VHOST_DIR}/
  configFile              ${VHOST_PATH}
  allowSymbolLink         1
  enableScript            1
  restrained              1
  setUIDMode              2
  user                    ${USERNAME}
  group                   ${USERNAME}
}
MAPEOF

  # Listener mapping
  ALL_DOMAINS="${DOMAIN}"
  [[ -n "${SERVER_ALIASES_COMMA}" ]] && ALL_DOMAINS="${DOMAIN},${SERVER_ALIASES_COMMA}"

  # Add to default HTTP listener (port 80)
  python3 -c "
import re
with open('${LISTENER_CONF}', 'r') as f:
    content = f.read()
# Add map to first 'listener Default' block (port 80)
new = re.sub(
    r'(listener\s+Default\s*\{[^}]*?)(\n\s*\})',
    r'\1\n  map                     ${VH_NAME} ${ALL_DOMAINS}\2',
    content, count=1, flags=re.DOTALL
)
with open('${LISTENER_CONF}', 'w') as f:
    f.write(new)
" 2>/dev/null || onx_log "warning: failed to inject listener map; manual edit may be required"
fi

# ── lswsctrl restart (OLS requires restart for vhost changes) ────────────────
if ! "${LSWS_CTL}" restart >/dev/null 2>&1; then
  onx_log "lswsctrl restart failed — rolling back"
  [[ -f "${BACKUP_PATH}" ]] && mv "${BACKUP_PATH}" "${VHOST_PATH}" || rm -f "${VHOST_PATH}"
  [[ -f "${LISTENER_BACKUP}" ]] && mv "${LISTENER_BACKUP}" "${LISTENER_CONF}"
  onx_die 4 "lswsctrl restart failed; vhost rolled back"
fi

rm -f "${BACKUP_PATH}" "${LISTENER_BACKUP}"

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