#!/usr/bin/env bash
set -euo pipefail

###############################################################################
# setup-cpanel-import-isolation.sh
#
# Installs the whp-cpanel-import@.service systemd unit so that future cPanel
# imports run inside a kernel-enforced filesystem sandbox.
#
# Background: see commit f7e4cbc and /tmp/cpanel-import-audit.md (if present).
# A hand-rolled recursive deleter in CpanelBackupImporter::removeDirectory()
# followed symlinks planted by a cPanel tarball and walked out of
# /tmp/cpanel_import_<id> into /etc and /usr/bin, unlink()ing every file. The
# PHP-layer fixes there close the specific bug; this script adds a defense-in-
# depth layer at the kernel layer via systemd namespace isolation, so a future
# regression cannot wipe host paths again.
#
# Idempotent.
###############################################################################

echo "=== Setting up cPanel import worker isolation ==="

# ---------------------------------------------------------------------------
# 1. Pre-create the writable paths the unit expects to exist
#
# ProtectSystem=strict + ReadWritePaths= bind-mounts the listed paths into
# the service mount namespace; if any path does not exist on disk, the unit
# fails to start. Idempotent mkdir keeps this safe to re-run.
# ---------------------------------------------------------------------------
echo "[paths] Ensuring writable host paths exist..."
mkdir -p /var/log/whp
mkdir -p /var/lib/whp
mkdir -p /var/lib/whp/cpanel-imports
chmod 700 /var/lib/whp/cpanel-imports

# /docker/users always exists on a provisioned WHP host (created in setup.sh),
# but a freshly-installed test VM may not have it yet; create defensively.
mkdir -p /docker/users

# /docker/powerdns/logs is normally created when PowerDNS is set up. The
# importer's DNS-zone calls into pdns-integration.php append to logs here; if
# the path is missing, our ReadWritePaths grant becomes a unit-start failure
# rather than a graceful degradation. Create the dir defensively.
mkdir -p /docker/powerdns/logs

# /var/log is part of the base OS - just ensure it is present.
mkdir -p /var/log
echo "[paths] Done."

# ---------------------------------------------------------------------------
# 2. Install the systemd template unit
# ---------------------------------------------------------------------------
SERVICE_SRC="/root/whp/configs/whp-cpanel-import@.service"
SERVICE_DST="/etc/systemd/system/whp-cpanel-import@.service"

if [ ! -f "$SERVICE_SRC" ]; then
    echo "[systemd] $SERVICE_SRC not yet synced (release rsync runs AFTER update scripts)."
    echo "[systemd] Falling through - re-run after rsync completes, or rely on legacy fallback path."
    echo "=== cPanel import isolation deferred ==="
    exit 0
fi

echo "[systemd] Installing $SERVICE_DST..."
cp "$SERVICE_SRC" "$SERVICE_DST"
chmod 644 "$SERVICE_DST"

# Verify the unit parses before we daemon-reload. systemd-analyze verify exits
# non-zero on critical syntax errors. Property warnings (e.g. "directive X is
# not understood, ignoring") print to stderr but do not fail verify.
if command -v systemd-analyze >/dev/null 2>&1; then
    echo "[systemd] Validating unit file..."
    if ! systemd-analyze verify "$SERVICE_DST" 2>&1 | tee /tmp/whp-cpanel-import-verify.out; then
        echo "[systemd] WARNING: systemd-analyze verify reported issues; review /tmp/whp-cpanel-import-verify.out"
        # Non-fatal: warnings about unknown properties on older systemd are OK.
        # If the unit truly fails to load, daemon-reload below will surface it.
    fi
fi

systemctl daemon-reload
echo "[systemd] Done."

# ---------------------------------------------------------------------------
# 3. Smoke-test: load the unit and check for fatal config errors
# ---------------------------------------------------------------------------
# We do NOT start a real instance (we have no import to run); instead, we
# ask systemd to load the template metadata. If the unit file has a fatal
# error (unrecognized [Section], malformed Property= line), this will fail.
echo "[systemd] Smoke-testing unit load..."
if systemctl cat whp-cpanel-import@.service >/dev/null 2>&1; then
    echo "[systemd] Unit loaded cleanly."
else
    echo "[systemd] WARNING: unit did not load cleanly. Run:"
    echo "          systemctl cat whp-cpanel-import@.service"
    echo "          journalctl -xe"
fi

# ---------------------------------------------------------------------------
# 4. Logrotate for the per-import log files
#
# The unit writes /var/log/cpanel-import-<id>.log via
# StandardOutput=append:. Old logs accumulate one file per import; rotate by
# age so the directory does not grow unbounded.
# ---------------------------------------------------------------------------
LOGROTATE_CONF="/etc/logrotate.d/whp-cpanel-import"
echo "[logrotate] Writing ${LOGROTATE_CONF}..."
cat > "$LOGROTATE_CONF" <<'LOGROTATE_EOF'
/var/log/cpanel-import-*.log {
    weekly
    rotate 4
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
}
LOGROTATE_EOF
echo "[logrotate] Done."

echo "=== cPanel import isolation setup complete ==="
echo ""
echo "Verify with:"
echo "  systemctl cat whp-cpanel-import@.service"
echo "  systemd-analyze security whp-cpanel-import@.service   # (after first real import)"
