#!/bin/bash

# One-time setup for the per-domain SSL certificate upload feature.
#
# Creates the directories the app writes to, ensures ownership matches
# the php-fpm user (so PHP can write) with group-read for caddy (so
# the running Caddy process can read certs and snippet files), and
# patches /etc/caddy/Caddyfile to expose the admin API on a unix
# socket and import per-domain snippets.
#
# Idempotent — safe to re-run.

set -euo pipefail

WEB_USER="${1:-www-data}"
CADDY_USER="${2:-caddy}"
CERT_DIR="/var/lib/multiportal/certs"
CADDY_CONF_D="/etc/caddy/conf.d"
CADDY_LOG_DIR="/var/log/caddy"
CADDYFILE="/etc/caddy/Caddyfile"
ADMIN_SOCKET_DIR="/run/caddy"

if [[ $EUID -ne 0 ]]; then
    echo "This script needs root (run with sudo)." >&2
    exit 1
fi

if ! id -u "$WEB_USER" >/dev/null 2>&1; then
    echo "Web user '$WEB_USER' does not exist." >&2
    exit 1
fi
if ! id -u "$CADDY_USER" >/dev/null 2>&1; then
    echo "Caddy user '$CADDY_USER' does not exist." >&2
    exit 1
fi

if ! id -nG "$CADDY_USER" | tr ' ' '\n' | grep -qx "$WEB_USER"; then
    echo "Adding $CADDY_USER to $WEB_USER group so PHP-written files are readable by Caddy..."
    usermod -aG "$WEB_USER" "$CADDY_USER"
fi

# Caddy talks to PHP via its default TCP admin endpoint at localhost:2019.
# We tried a unix socket originally but Caddy 2.x resets the socket's
# perms to 0200 on every reload, which made the socket unusable after
# the first reload. TCP localhost has no perms to fight and is bound to
# 127.0.0.1 only, so it's not externally reachable.

echo "Creating $CERT_DIR (owner $WEB_USER:$CADDY_USER, mode 0750)..."
mkdir -p "$CERT_DIR"
chown "$WEB_USER:$CADDY_USER" "$CERT_DIR"
chmod 0750 "$CERT_DIR"

echo "Creating $CADDY_CONF_D (owner $WEB_USER:$CADDY_USER, mode 0750)..."
mkdir -p "$CADDY_CONF_D"
chown "$WEB_USER:$CADDY_USER" "$CADDY_CONF_D"
chmod 0750 "$CADDY_CONF_D"

if [[ ! -d "$CADDY_LOG_DIR" ]]; then
    echo "Creating $CADDY_LOG_DIR (owner $CADDY_USER:$CADDY_USER, mode 0755)..."
    mkdir -p "$CADDY_LOG_DIR"
    chown "$CADDY_USER:$CADDY_USER" "$CADDY_LOG_DIR"
    chmod 0755 "$CADDY_LOG_DIR"
fi

# Admin endpoint is now TCP localhost:2019 (Caddy's default) —
# no socket directory needed.

# Strip any prior admin unix-socket directive from the Caddyfile —
# we now use the default TCP localhost:2019 endpoint.
if grep -q 'admin unix//run/caddy/admin.sock' "$CADDYFILE"; then
    echo "Removing legacy admin unix socket directive from $CADDYFILE..."
    cp "$CADDYFILE" "$CADDYFILE.pre-cert.$(date +%Y%m%d-%H%M%S).bak"
    sed -i -E '/^[[:space:]]*admin[[:space:]]+unix\/\/run\/caddy\/admin\.sock.*$/d' "$CADDYFILE"
fi

if grep -q 'import conf.d/\*.caddy' "$CADDYFILE"; then
    echo "Caddyfile already has 'import conf.d/*.caddy' — skipping import patch."
else
    echo "Appending 'import conf.d/*.caddy' to $CADDYFILE..."
    {
        echo ""
        echo "# Per-domain uploaded SSL certificate snippets — managed by the portal."
        echo "import conf.d/*.caddy"
    } >> "$CADDYFILE"
fi

# Remove any prior systemd drop-in that fought socket perms — no longer
# relevant now that we use the default TCP admin endpoint.
DROPIN_FILE="/etc/systemd/system/caddy.service.d/admin-socket-perms.conf"
NEEDS_DROPIN_RESTART=0
if [[ -f "$DROPIN_FILE" ]]; then
    echo "Removing legacy systemd drop-in $DROPIN_FILE..."
    rm -f "$DROPIN_FILE"
    systemctl daemon-reload
    NEEDS_DROPIN_RESTART=1
fi

echo "Validating new Caddyfile..."
if ! su -s /bin/sh -c "caddy validate --config $CADDYFILE" "$CADDY_USER" >/dev/null 2>&1; then
    echo "Caddyfile validation failed. Inspect $CADDYFILE — restore from latest .bak if needed." >&2
    su -s /bin/sh -c "caddy validate --config $CADDYFILE" "$CADDY_USER" || true
    exit 1
fi

# Restart if we just removed the drop-in or stripped the admin directive,
# else a normal reload is enough.
if [[ "$NEEDS_DROPIN_RESTART" == "1" ]]; then
    echo "Restarting Caddy (admin endpoint changed)..."
    systemctl restart caddy
else
    echo "Reloading Caddy..."
    systemctl reload caddy
fi

# Verify the admin endpoint is reachable on TCP localhost:2019.
sleep 1
if curl -fsS --max-time 2 http://localhost:2019/config/ >/dev/null 2>&1; then
    echo "Admin endpoint reachable: http://localhost:2019"
else
    echo "WARN: http://localhost:2019 did not respond — check 'systemctl status caddy'." >&2
fi

cat <<EOF

Setup complete.

Directories:
  $CERT_DIR      (cert+key files, written by $WEB_USER)
  $CADDY_CONF_D  (per-domain Caddyfile snippets)

Caddy admin endpoint: http://localhost:2019 (default, 127.0.0.1-only)
PHP-FPM can reload Caddy via:
  caddy reload --config $CADDYFILE --address localhost:2019

Next: log in to the portal as a reseller/tenant with branding-management
permission, open the custom-domain card, click the SSL key icon on a
verified domain, and upload a cert + key.
EOF
