#!/bin/bash

# Server-side Deployment Script für Custom PHP Framework
# Läuft auf dem Production-Server (94.16.110.151)

set -euo pipefail  # Exit on any error

DEPLOY_TAG="$1"
DEPLOY_PATH="$2"
BACKUP_PATH="${DEPLOY_PATH}-backup-$(date +%Y%m%d-%H%M%S)"
TEMP_PATH="${DEPLOY_PATH}-deploying"

# Farben
GREEN="\e[32m"
YELLOW="\e[33m" 
RED="\e[31m"
BLUE="\e[34m"
RESET="\e[0m"

log() {
    echo -e "${BLUE}[SERVER $(date +'%H:%M:%S')]${RESET} $1"
}

success() {
    echo -e "${GREEN}✅ $1${RESET}"
}

error() {
    echo -e "${RED}❌ $1${RESET}"
    cleanup_on_error
    exit 1
}

cleanup_on_error() {
    log "Cleanup nach Fehler..."
    [[ -d "$TEMP_PATH" ]] && rm -rf "$TEMP_PATH"
    [[ -d "$BACKUP_PATH" ]] && {
        log "Stelle vorherige Version wieder her..."
        [[ -d "$DEPLOY_PATH" ]] && rm -rf "$DEPLOY_PATH"
        mv "$BACKUP_PATH" "$DEPLOY_PATH"
        cd "$DEPLOY_PATH" && docker compose restart
    }
}

# Atomic Deployment mit Git
atomic_git_deployment() {
    log "Starte atomic git deployment..."
    
    # 1. Backup der aktuellen Version erstellen
    if [[ -d "$DEPLOY_PATH" ]]; then
        log "Erstelle Backup der aktuellen Version..."
        cp -r "$DEPLOY_PATH" "$BACKUP_PATH"
        success "Backup erstellt: $BACKUP_PATH"
    fi
    
    # 2. Neue Version in temporäres Verzeichnis clonen
    log "Clone neue Version mit Tag: $DEPLOY_TAG"
    
    if [[ -d "$TEMP_PATH" ]]; then
        rm -rf "$TEMP_PATH"
    fi
    
    # Git Repository klonen oder pullen
    if [[ -d "$DEPLOY_PATH/.git" ]]; then
        # Existierendes Repository - fetch und checkout
        log "Update existierendes Repository..."
        cd "$DEPLOY_PATH"
        git fetch --tags origin
        git checkout "$DEPLOY_TAG"
        success "Git checkout zu $DEPLOY_TAG erfolgreich"
    else
        # Neues Repository klonen
        log "Klone Repository neu..."
        git clone --depth 1 --branch "$DEPLOY_TAG" "$(git -C . remote get-url origin)" "$TEMP_PATH" || {
            error "Git clone fehlgeschlagen"
        }
        
        # Atomic Switch: Temp → Live
        if [[ -d "$DEPLOY_PATH" ]]; then
            mv "$DEPLOY_PATH" "${DEPLOY_PATH}-old"
        fi
        mv "$TEMP_PATH" "$DEPLOY_PATH"
    fi
}

# Framework-spezifische Deployment-Schritte  
framework_deployment() {
    log "Führe Framework-Deployment durch..."
    
    cd "$DEPLOY_PATH"
    
    # 1. Environment Setup
    if [[ ! -f .env ]]; then
        if [[ -f .env.production ]]; then
            log "Kopiere .env.production zu .env"
            cp .env.production .env
        else
            error ".env.production nicht gefunden"
        fi
    fi
    
    # 2. Composer Dependencies (Production)
    log "Installiere Composer Dependencies..."
    if ! composer install --no-dev --optimize-autoloader --no-interaction; then
        error "Composer Install fehlgeschlagen"
    fi
    
    # 3. Framework Cache warming (falls implementiert)
    if [[ -f console.php ]] && php console.php list | grep -q "cache:warm"; then
        log "Wärme Framework Caches auf..."
        php console.php cache:warm || warning "Cache warming fehlgeschlagen"
    fi
    
    # 4. Database Migrations
    log "Führe Database Migrations durch..."
    if php console.php list | grep -q "db:migrate"; then
        php console.php db:migrate || error "Database Migration fehlgeschlagen"
    else
        warning "Keine Database Migrations gefunden"
    fi
    
    # 5. Framework optimizations
    if php console.php list | grep -q "framework:optimize"; then
        log "Optimiere Framework..."
        php console.php framework:optimize || warning "Framework Optimization fehlgeschlagen"
    fi
    
    success "Framework-Deployment abgeschlossen"
}

# Docker Services Management
manage_docker_services() {
    log "Manage Docker Services..."
    
    cd "$DEPLOY_PATH"
    
    # Prüfe ob docker-compose.yml existiert
    if [[ ! -f docker-compose.yml ]]; then
        error "docker-compose.yml nicht gefunden"
    fi
    
    # Services neu starten mit minimaler Downtime
    log "Starte Services neu..."
    
    # Rolling Update Strategy
    docker compose pull --quiet || warning "Docker Pull Warnings (nicht kritisch)"
    
    # Restart mit Health Checks
    if docker compose up -d --force-recreate --remove-orphans; then
        success "Docker Services erfolgreich neu gestartet"
    else
        error "Docker Restart fehlgeschlagen"
    fi
    
    # Warte auf Service-Start
    log "Warte auf Service-Start..."
    sleep 10
}

# Health Checks
health_checks() {
    log "Führe Health Checks durch..."
    
    cd "$DEPLOY_PATH"
    
    # 1. Framework Health Check
    if php console.php health:check; then
        success "Framework Health Check OK"
    else
        error "Framework Health Check fehlgeschlagen"
    fi
    
    # 2. Docker Services Check
    if ! docker compose ps | grep -q "Up"; then
        error "Docker Services nicht verfügbar"
    fi
    success "Docker Services OK"
    
    # 3. MCP Server Test (optional)
    if timeout 5 php console.php mcp:server --test 2>/dev/null; then
        success "MCP Server OK"
    else
        log "MCP Server Test übersprungen (optional)"
    fi
    
    # 4. Web Response Test
    sleep 5
    if curl -f -s -H "User-Agent: Mozilla/5.0 (Deployment Health Check)" "http://localhost" > /dev/null; then
        success "HTTP Response OK"
    else
        warning "HTTP Response Test fehlgeschlagen (möglicherweise nginx-Problem)"
    fi
}

# Cleanup alte Backups (behalte nur die letzten 5)
cleanup_old_backups() {
    log "Räume alte Backups auf..."
    
    # Finde alle Backup-Ordner und behalte nur die 5 neuesten
    find "$(dirname "$DEPLOY_PATH")" -maxdepth 1 -name "*-backup-*" -type d | \
        sort -r | \
        tail -n +6 | \
        xargs -r rm -rf
    
    success "Backup-Cleanup abgeschlossen"
}

# Deployment-Summary
deployment_summary() {
    echo -e "${GREEN}"
    echo "🎉 Server-Deployment erfolgreich!"
    echo "📋 Tag: $DEPLOY_TAG"
    echo "📁 Path: $DEPLOY_PATH"
    echo "💾 Backup: $BACKUP_PATH"
    echo "⏰ Zeit: $(date)"
    echo -e "${RESET}"
}

# Hauptprogramm
main() {
    log "🚀 Server-side Deployment gestartet"
    log "📦 Tag: $DEPLOY_TAG"
    log "📁 Path: $DEPLOY_PATH"
    
    atomic_git_deployment
    framework_deployment
    manage_docker_services
    health_checks
    cleanup_old_backups
    deployment_summary
    
    # Cleanup erfolgreicher Deployment
    [[ -d "${DEPLOY_PATH}-old" ]] && rm -rf "${DEPLOY_PATH}-old"
}

# Error Handling
trap cleanup_on_error ERR

# Script ausführen  
main "$@"