#!/usr/bin/env bash
# Isolate a broken SSL vhost: disable only that domain so Apache can start,
# keeping all other sites live. Fully reversible.
#
# Usage: isolate-broken-vhost <domain>
#        isolate-broken-vhost --restore <domain>

set -euo pipefail

QUARANTINE_DIR="/opt/server-resilience/backups/quarantine"
LOG_FILE="/opt/server-resilience/logs/isolate-$(date +%Y%m%d).log"
SSL_TLS_DIR="/var/cpanel/ssl/apache_tls"
USERDATA_DIR="/var/cpanel/userdata"
CONF_D="/etc/apache2/conf.d"

mkdir -p "$QUARANTINE_DIR"

log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"; }

usage() {
    echo "Usage: $0 <domain>            -- isolate broken domain"
    echo "       $0 --restore <domain>  -- restore previously isolated domain"
    exit 1
}

[[ $# -lt 1 ]] && usage

if [[ "$1" == "--restore" ]]; then
    DOMAIN="${2:-}"
    [[ -z "$DOMAIN" ]] && usage
    BACKUP="$QUARANTINE_DIR/$DOMAIN"

    if [[ ! -d "$BACKUP" ]]; then
        echo "No quarantine backup found for: $DOMAIN"
        exit 1
    fi

    log "Restoring $DOMAIN from quarantine"

    # Restore apache_tls key
    if [[ -f "$BACKUP/key" ]]; then
        install -m 600 "$BACKUP/key" "$SSL_TLS_DIR/$DOMAIN/key"
        log "Restored key for $DOMAIN"
    fi

    # Restore combined cert
    if [[ -f "$BACKUP/combined" ]]; then
        install -m 640 "$BACKUP/combined" "$SSL_TLS_DIR/$DOMAIN/combined"
        log "Restored combined for $DOMAIN"
    fi

    # Restore custom conf.d SSL file if exists
    if [[ -f "$BACKUP/conf.d.conf" ]]; then
        CONFNAME=$(cat "$BACKUP/conf.d.confname" 2>/dev/null || echo "${DOMAIN//./_}_ssl.conf")
        install -m 644 "$BACKUP/conf.d.conf" "$CONF_D/$CONFNAME"
        log "Restored conf.d/$CONFNAME"
    fi

    # Restore SSL userdata
    if [[ -f "$BACKUP/userdata_SSL" ]]; then
        CPANEL_USER=$(cat "$BACKUP/cpanel_user" 2>/dev/null || echo "")
        if [[ -n "$CPANEL_USER" ]]; then
            install -m 600 "$BACKUP/userdata_SSL" "$USERDATA_DIR/$CPANEL_USER/${DOMAIN}_SSL"
            log "Restored userdata SSL for $DOMAIN"
        fi
    fi

    echo "Restored $DOMAIN. Run: httpd -t && systemctl restart httpd"
    exit 0
fi

DOMAIN="$1"
BACKUP="$QUARANTINE_DIR/$DOMAIN"

log "Isolating broken vhost: $DOMAIN"
mkdir -p "$BACKUP"
echo "$DOMAIN" > "$BACKUP/domain"
date >> "$BACKUP/isolated_at"

# ─── Find cPanel user for this domain ────────────────────────────────────────
CPANEL_USER=$(grep -r "^$DOMAIN:" /etc/userdatadomains 2>/dev/null | cut -d= -f2 | cut -d= -f1 || true)
if [[ -z "$CPANEL_USER" ]]; then
    # Try to find via userdata dirs
    CPANEL_USER=$(find "$USERDATA_DIR" -name "${DOMAIN}_SSL" 2>/dev/null | awk -F/ '{print $5}' | head -1 || true)
fi
echo "$CPANEL_USER" > "$BACKUP/cpanel_user"
log "cPanel user: $CPANEL_USER"

# ─── Backup and disable the SSL cert files ───────────────────────────────────
if [[ -d "$SSL_TLS_DIR/$DOMAIN" ]]; then
    log "Backing up SSL files for $DOMAIN"
    [[ -f "$SSL_TLS_DIR/$DOMAIN/key" ]] && \
        install -m 600 "$SSL_TLS_DIR/$DOMAIN/key" "$BACKUP/key"
    [[ -f "$SSL_TLS_DIR/$DOMAIN/combined" ]] && \
        install -m 640 "$SSL_TLS_DIR/$DOMAIN/combined" "$BACKUP/combined"
fi

# ─── Disable: redirect SSL to HTTP-only by using a dummy self-signed cert ────
# This allows Apache to start; the vhost will be non-functional but others live.
log "Generating emergency self-signed cert for $DOMAIN (allows Apache to load)"
openssl req -x509 -newkey rsa:2048 -keyout "$SSL_TLS_DIR/$DOMAIN/key" \
    -out /tmp/emergency_cert_$$.pem \
    -days 1 -nodes \
    -subj "/CN=$DOMAIN/O=EMERGENCY/C=CA" 2>/dev/null
cat /tmp/emergency_cert_$$.pem > "$SSL_TLS_DIR/$DOMAIN/combined"
rm -f /tmp/emergency_cert_$$.pem
chmod 600 "$SSL_TLS_DIR/$DOMAIN/key"
chmod 640 "$SSL_TLS_DIR/$DOMAIN/combined"
log "Emergency self-signed cert installed for $DOMAIN"

# ─── Also disable any custom conf.d vhost file for this domain ───────────────
SLUG="${DOMAIN//./_}"
for conf_candidate in "$CONF_D/${SLUG}_ssl.conf" "$CONF_D/${SLUG}.conf"; do
    if [[ -f "$conf_candidate" ]]; then
        install -m 644 "$conf_candidate" "$BACKUP/conf.d.conf"
        basename "$conf_candidate" > "$BACKUP/conf.d.confname"
        # Rename to .disabled so Apache ignores it
        mv "$conf_candidate" "${conf_candidate}.ISOLATED"
        log "Disabled conf.d: $(basename $conf_candidate)"
    fi
done

# ─── Verify Apache can now start ─────────────────────────────────────────────
log "Testing Apache syntax after isolation"
if httpd -t 2>&1; then
    log "Syntax OK after isolating $DOMAIN"
    echo ""
    echo "✓ $DOMAIN has been isolated."
    echo "  - Emergency cert installed (site will show SSL error but Apache loads)"
    echo "  - All other sites remain live"
    echo "  - Backup: $BACKUP"
    echo ""
    echo "To fix: reinstall correct cert via WHM > SSL/TLS > Install SSL, then:"
    echo "  $0 --restore $DOMAIN"
else
    log "Still broken after isolating $DOMAIN - more issues exist"
    echo "WARNING: Apache still broken after isolating $DOMAIN"
    echo "Run: /opt/server-resilience/bin/preflight-check  to find remaining issues"
fi
