#!/bin/bash
# ─────────────────────────────────────────────────────────────
# deploy-platform.sh
# Deploys the latest locally-pulled platform backup.
# Self-healing: installs all required system dependencies.
# Only redeploys if the backup is newer than the running version.
# Run every hour (offset ~5min after pull) via cron.
# ─────────────────────────────────────────────────────────────

LOCAL_BACKUP_DIR="/backups/platform"
DEPLOY_DIR="/root/management-platform"
OLD_DEPLOY_DIR="/backups/platform/old-deploys"
STAMP_FILE="/backups/platform/.last-deployed"
SERVICE_FILE="/etc/systemd/system/management-platform.service"
LOG="/root/deploy-platform.log"

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

mkdir -p "$OLD_DEPLOY_DIR"

# ════════════════════════════════════════════════════════════
# STEP 1 — Check & install system dependencies
# ════════════════════════════════════════════════════════════
log "🔍 Checking system dependencies..."

MISSING_PKGS=""

# python3
if ! command -v python3 &>/dev/null; then
    MISSING_PKGS="$MISSING_PKGS python3"
fi

# python3-venv (needed for venv creation)
PYTHON_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")' 2>/dev/null)
if ! python3 -c "import ensurepip" &>/dev/null; then
    MISSING_PKGS="$MISSING_PKGS python${PYTHON_VERSION}-venv"
fi

# sshpass (used by restore feature)
if ! command -v sshpass &>/dev/null; then
    MISSING_PKGS="$MISSING_PKGS sshpass"
fi

if [ -n "$MISSING_PKGS" ]; then
    log "📦 Installing missing packages:$MISSING_PKGS"
    apt-get update -qq
    apt-get install -y --quiet $MISSING_PKGS
    if [ $? -ne 0 ]; then
        log "❌ apt install failed — check internet/apt on this machine"
        exit 1
    fi
    log "✅ System packages installed"
else
    log "✅ System dependencies OK"
fi

# ════════════════════════════════════════════════════════════
# STEP 2 — Find latest local backup
# ════════════════════════════════════════════════════════════
LATEST=$(ls -t "$LOCAL_BACKUP_DIR"/platform-backup-*.tar.gz 2>/dev/null | head -1)

if [ -z "$LATEST" ]; then
    log "❌ No local platform backups found in $LOCAL_BACKUP_DIR"
    log "   Run pull-platform-backup.sh first"
    exit 1
fi

BACKUP_NAME=$(basename "$LATEST")

# ── Check if already deployed ─────────────────────────────────
if [ -f "$STAMP_FILE" ] && [ "$(cat $STAMP_FILE)" = "$BACKUP_NAME" ]; then
    log "✅ Already running latest: $BACKUP_NAME — nothing to do"
    exit 0
fi

log "🚀 New backup detected: $BACKUP_NAME — deploying..."

# ════════════════════════════════════════════════════════════
# STEP 3 — Extract & validate
# ════════════════════════════════════════════════════════════
EXTRACT_DIR=$(mktemp -d /tmp/platform-deploy-XXXXXX)
log "📂 Extracting to $EXTRACT_DIR ..."

tar -xzf "$LATEST" -C "$EXTRACT_DIR"
if [ $? -ne 0 ]; then
    log "❌ tar extraction failed — backup may be corrupt: $BACKUP_NAME"
    rm -rf "$EXTRACT_DIR"
    exit 1
fi

# Find management-platform/ inside archive (handles any nesting level)
PLATFORM_SRC=$(find "$EXTRACT_DIR" -maxdepth 3 -type d -name "management-platform" | head -1)

if [ -z "$PLATFORM_SRC" ]; then
    log "❌ Could not find management-platform/ inside archive"
    log "   Archive contents:"
    find "$EXTRACT_DIR" -maxdepth 3 | head -20 | tee -a "$LOG"
    rm -rf "$EXTRACT_DIR"
    exit 1
fi

if [ ! -f "$PLATFORM_SRC/app.py" ]; then
    log "❌ app.py not found in extracted platform — archive looks wrong"
    rm -rf "$EXTRACT_DIR"
    exit 1
fi

log "✅ Found platform at: $PLATFORM_SRC"

# Strip venv and cache from source — always rebuild locally
rm -rf "$PLATFORM_SRC/venv" "$PLATFORM_SRC/__pycache__"
find "$PLATFORM_SRC" -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null

# ════════════════════════════════════════════════════════════
# STEP 4 — Stop service & kill strays
# ════════════════════════════════════════════════════════════
log "🛑 Stopping management-platform service..."
systemctl stop management-platform 2>/dev/null
sleep 2
pkill -f "python.*app.py" 2>/dev/null
sleep 1

# ════════════════════════════════════════════════════════════
# STEP 5 — Archive current deploy, swap in new one
# ════════════════════════════════════════════════════════════
if [ -d "$DEPLOY_DIR" ] && [ "$(ls -A $DEPLOY_DIR 2>/dev/null)" ]; then
    OLD_NAME="management-platform.old.$(date +%Y%m%d_%H%M%S)"
    log "📦 Archiving current deploy → $OLD_DEPLOY_DIR/$OLD_NAME.tar.gz"
    tar -czf "$OLD_DEPLOY_DIR/$OLD_NAME.tar.gz" -C /root management-platform 2>/dev/null
    rm -rf "$DEPLOY_DIR"
    # Keep only last 2 old deploys
    ls -t "$OLD_DEPLOY_DIR"/management-platform.old.*.tar.gz 2>/dev/null \
        | tail -n +3 | xargs rm -f 2>/dev/null
fi

# Remove any leftover .old directories in /root from old scripts
rm -rf /root/management-platform.old.* 2>/dev/null

log "📁 Deploying new version..."
cp -r "$PLATFORM_SRC" "$DEPLOY_DIR"

chmod +x "$DEPLOY_DIR"/*.sh 2>/dev/null
chmod +x "$DEPLOY_DIR"/*.py 2>/dev/null

# ════════════════════════════════════════════════════════════
# STEP 6 — Build fresh venv & install flask
# ════════════════════════════════════════════════════════════
log "🐍 Building fresh Python venv..."
cd "$DEPLOY_DIR"

python3 -m venv venv
if [ $? -ne 0 ]; then
    log "❌ venv creation failed"
    rm -rf "$EXTRACT_DIR"
    exit 1
fi

# Bootstrap pip in case ensurepip is incomplete
venv/bin/python -m ensurepip --upgrade 2>/dev/null || true
venv/bin/python -m pip install --upgrade pip --quiet 2>/dev/null || true

log "📦 Installing Flask..."
venv/bin/pip install flask --quiet
if [ $? -ne 0 ]; then
    log "❌ Flask install failed"
    rm -rf "$EXTRACT_DIR"
    exit 1
fi

log "✅ Venv ready ($(venv/bin/python --version), flask $(venv/bin/pip show flask | grep Version | cut -d' ' -f2))"

# ════════════════════════════════════════════════════════════
# STEP 7 — Write correct systemd service file
# ════════════════════════════════════════════════════════════
log "🔧 Writing systemd service file..."
cat > "$SERVICE_FILE" << 'SVCEOF'
[Unit]
Description=Navitrends Management Platform
After=network.target docker.target
Wants=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/root/management-platform
ExecStart=/root/management-platform/venv/bin/python /root/management-platform/app.py
Restart=on-failure
RestartSec=10
StartLimitIntervalSec=60
StartLimitBurst=3
StandardOutput=append:/root/management-platform/app.log
StandardError=append:/root/management-platform/app.log

[Install]
WantedBy=multi-user.target
SVCEOF

systemctl daemon-reload

# ════════════════════════════════════════════════════════════
# STEP 8 — Clean up & start
# ════════════════════════════════════════════════════════════
rm -rf "$EXTRACT_DIR"

log "▶️  Starting management-platform service..."
systemctl start management-platform
sleep 4

if systemctl is-active --quiet management-platform; then
    log "✅ Service is running"
    echo "$BACKUP_NAME" > "$STAMP_FILE"
    log "🎉 Deploy complete: $BACKUP_NAME"
else
    log "❌ Service failed to start. Last app.log lines:"
    tail -20 "$DEPLOY_DIR/app.log" | tee -a "$LOG"
    log "   Full check: journalctl -u management-platform -n 30"
    exit 1
fi
