#!/usr/bin/env bash
# Safe Apache restart with: preflight check → config backup → restart → rollback on failure
# This is THE command for all Apache restarts/reloads on this server.
#
# Usage: safe-apache-restart [reload|restart|graceful]

set -euo pipefail

ACTION="${1:-graceful}"
BACKUP_DIR="/opt/server-resilience/backups/apache-configs"
LOG_FILE="/opt/server-resilience/logs/restart-$(date +%Y%m%d).log"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LAST_GOOD_MARKER="/opt/server-resilience/etc/last-good-config"
PREFLIGHT="/opt/server-resilience/bin/preflight-check"
ALERT_SCRIPT="/opt/server-resilience/bin/send-alert"
MAX_ROLLBACK_ATTEMPTS=3

mkdir -p "$BACKUP_DIR"

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'; BOLD='\033[1m'

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

[[ "$ACTION" =~ ^(reload|restart|graceful|graceful-stop)$ ]] || \
    die "Invalid action: $ACTION. Use: reload | restart | graceful"

log "=== safe-apache-restart ACTION=$ACTION ==="

# ─── Step 1: Preflight check ─────────────────────────────────────────────────
echo -e "\n${BOLD}Step 1: Running preflight checks...${NC}"
if ! "$PREFLIGHT"; then
    log "Preflight FAILED - aborting restart"
    echo -e "${RED}Restart ABORTED: preflight check failed.${NC}"
    echo "Run preflight-check for details. Fix issues, then retry."
    "$ALERT_SCRIPT" "BLOCKED" "safe-apache-restart blocked by preflight failure" 2>/dev/null || true
    exit 1
fi

# ─── Step 2: Backup current config ───────────────────────────────────────────
echo -e "\n${BOLD}Step 2: Backing up current config...${NC}"
BACKUP_SNAPSHOT="$BACKUP_DIR/snapshot-$TIMESTAMP"
mkdir -p "$BACKUP_SNAPSHOT"

# Save full httpd.conf
install -m 644 /etc/apache2/conf/httpd.conf "$BACKUP_SNAPSHOT/httpd.conf"
# Save conf.d SSL configs
tar -czf "$BACKUP_SNAPSHOT/conf.d.tar.gz" /etc/apache2/conf.d/ 2>/dev/null || true
# Save userdata SSL yaml files
tar -czf "$BACKUP_SNAPSHOT/userdata-ssl.tar.gz" /var/cpanel/userdata/*/\*_SSL* 2>/dev/null || true
echo "$TIMESTAMP" > "$BACKUP_SNAPSHOT/timestamp"
echo "OK" > "$BACKUP_SNAPSHOT/status"

log "Config backed up to: $BACKUP_SNAPSHOT"
echo "  Backed up to: $BACKUP_SNAPSHOT"

# Record backup location for rollback
echo "$BACKUP_SNAPSHOT" > "$LAST_GOOD_MARKER.pending"

# Keep only last 10 snapshots
ls -t "$BACKUP_DIR"/snapshot-* 2>/dev/null | tail -n +11 | xargs rm -rf 2>/dev/null || true

# ─── Step 3: Check current Apache state ──────────────────────────────────────
WAS_RUNNING=false
if systemctl is-active httpd &>/dev/null; then
    WAS_RUNNING=true
fi

# ─── Step 4: Execute the action ──────────────────────────────────────────────
echo -e "\n${BOLD}Step 3: Executing: httpd $ACTION${NC}"
log "Executing: $ACTION (was_running=$WAS_RUNNING)"

case "$ACTION" in
    reload)
        RESTART_CMD="systemctl reload httpd"
        ;;
    graceful)
        RESTART_CMD="apachectl graceful"
        ;;
    *)
        RESTART_CMD="systemctl restart httpd"
        ;;
esac

if $RESTART_CMD 2>&1 | tee -a "$LOG_FILE"; then
    sleep 2
    # Verify it's actually running
    if systemctl is-active httpd &>/dev/null; then
        log "Apache started/reloaded successfully"
        echo -e "\n${GREEN}✓ Apache $ACTION successful${NC}"
        # Promote pending to last-good
        [[ -f "$LAST_GOOD_MARKER.pending" ]] && mv "$LAST_GOOD_MARKER.pending" "$LAST_GOOD_MARKER"
        echo "$BACKUP_SNAPSHOT" > "$LAST_GOOD_MARKER"
        echo "OK" > "$BACKUP_SNAPSHOT/status"
        exit 0
    fi
fi

# ─── Step 5: ROLLBACK ────────────────────────────────────────────────────────
echo -e "\n${RED}Apache failed to start/reload. Initiating rollback...${NC}"
log "Restart FAILED - initiating rollback"
"$ALERT_SCRIPT" "DOWN" "Apache failed to restart - rolling back config" 2>/dev/null || true

LAST_GOOD=$(cat "$LAST_GOOD_MARKER" 2>/dev/null || true)

if [[ -n "$LAST_GOOD" && -d "$LAST_GOOD" ]]; then
    log "Rolling back to: $LAST_GOOD"
    echo "Rolling back to known-good: $LAST_GOOD"

    # Restore httpd.conf
    if [[ -f "$LAST_GOOD/httpd.conf" ]]; then
        install -m 644 "$LAST_GOOD/httpd.conf" /etc/apache2/conf/httpd.conf
        log "Restored httpd.conf from backup"
    fi

    # Restore conf.d
    if [[ -f "$LAST_GOOD/conf.d.tar.gz" ]]; then
        tar -xzf "$LAST_GOOD/conf.d.tar.gz" -C / 2>/dev/null || true
        log "Restored conf.d from backup"
    fi

    # Try to start with restored config
    for attempt in $(seq 1 $MAX_ROLLBACK_ATTEMPTS); do
        log "Rollback restart attempt $attempt/$MAX_ROLLBACK_ATTEMPTS"
        if systemctl start httpd 2>&1 | tee -a "$LOG_FILE" && systemctl is-active httpd &>/dev/null; then
            log "Apache started with rolled-back config"
            echo -e "${GREEN}✓ Rollback successful - Apache running with previous config${NC}"
            "$ALERT_SCRIPT" "RECOVERED" "Apache recovered via config rollback to $LAST_GOOD" 2>/dev/null || true
            echo ""
            echo "IMPORTANT: The config change was rolled back."
            echo "Investigate the issue, then retry: safe-apache-restart"
            exit 2  # Exit 2 = rolled back (partial success)
        fi
        sleep 3
    done

    log "Rollback ALSO FAILED after $MAX_ROLLBACK_ATTEMPTS attempts"
    echo -e "${RED}CRITICAL: Rollback also failed. Apache is DOWN.${NC}"
    "$ALERT_SCRIPT" "CRITICAL" "Apache DOWN - restart AND rollback both failed. Manual intervention required." 2>/dev/null || true
    exit 3
else
    log "No last-known-good backup available for rollback"
    echo -e "${RED}No rollback backup available. Run: /opt/server-resilience/bin/preflight-check${NC}"
    exit 3
fi
