#!/bin/bash

# 🚀 VEZA DEVELOPMENT ENVIRONMENT STARTER
# Script principal pour démarrer l'environnement de développement

set -e

# Couleurs
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m'

# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DEV_ENV_DIR="$SCRIPT_DIR/dev-environment"
LOG_DIR="$SCRIPT_DIR/logs"
PID_DIR="$SCRIPT_DIR/logs"

# Fonction pour afficher les messages
log_info() {
    echo -e "${BLUE}ℹ️  $1${NC}"
}

log_success() {
    echo -e "${GREEN}✅ $1${NC}"
}

log_warning() {
    echo -e "${YELLOW}⚠️  $1${NC}"
}

log_error() {
    echo -e "${RED}❌ $1${NC}"
}

log_header() {
    echo -e "${PURPLE}$1${NC}"
}

# Fonction pour vérifier si une commande existe
command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# Fonction pour vérifier si un port est utilisé
port_in_use() {
    lsof -i :$1 >/dev/null 2>&1
}

# Fonction pour attendre qu'un service soit prêt
wait_for_service() {
    local url=$1
    local service_name=$2
    local max_attempts=30
    local attempt=0
    
    log_info "Attente que $service_name soit prêt..."
    
    while [ $attempt -lt $max_attempts ]; do
        if curl -s "$url" >/dev/null 2>&1; then
            log_success "$service_name est prêt!"
            return 0
        fi
        
        attempt=$((attempt + 1))
        sleep 2
    done
    
    log_error "$service_name n'est pas prêt après $((max_attempts * 2)) secondes"
    return 1
}

# Fonction pour démarrer un service
start_service() {
    local service_name=$1
    local start_command=$2
    local port=$3
    local working_dir=$4
    
    log_info "Démarrage de $service_name..."
    
    if port_in_use $port; then
        log_warning "Port $port déjà utilisé, $service_name pourrait déjà être en cours d'exécution"
        return 0
    fi
    
    cd "$working_dir"
    nohup $start_command > "$LOG_DIR/${service_name}.log" 2>&1 &
    local pid=$!
    echo $pid > "$PID_DIR/${service_name}.pid"
    
    log_success "$service_name démarré (PID: $pid)"
}

# Fonction pour arrêter un service
stop_service() {
    local service_name=$1
    local pid_file="$PID_DIR/${service_name}.pid"
    
    if [ -f "$pid_file" ]; then
        local pid=$(cat "$pid_file")
        if kill -0 $pid 2>/dev/null; then
            log_info "Arrêt de $service_name (PID: $pid)..."
            kill $pid
            rm "$pid_file"
            log_success "$service_name arrêté"
        else
            log_warning "$service_name n'était pas en cours d'exécution"
            rm "$pid_file"
        fi
    else
        log_warning "Fichier PID pour $service_name non trouvé"
    fi
}

# Fonction pour vérifier l'état des services
check_services() {
    log_header "🔍 Vérification de l'état des services..."
    
    local services=("postgresql" "redis-server")
    
    for service in "${services[@]}"; do
        if systemctl is-active --quiet $service; then
            log_success "$service est actif"
        else
            log_error "$service n'est pas actif"
            return 1
        fi
    done
}

# Fonction pour démarrer tous les services
start_all_services() {
    log_header "🚀 Démarrage de tous les services Veza..."
    
    # Création des répertoires nécessaires
    mkdir -p "$LOG_DIR" "$PID_DIR"
    
    # Vérification des services système
    if ! check_services; then
        log_error "Services système non disponibles"
        exit 1
    fi
    
    # Démarrage des services Veza
    start_service "backend-api" "go run cmd/modern-server/main.go" 8080 "veza-backend-api"
    start_service "chat-server" "cargo run" 3001 "veza-chat-server"
    start_service "stream-server" "cargo run" 8000 "veza-stream-server"
    start_service "frontend" "npm run dev" 3000 "veza-frontend"
    
    # Attente que les services soient prêts
    wait_for_service "http://localhost:8080/health" "Backend API"
    wait_for_service "http://localhost:3001/health" "Chat Server"
    wait_for_service "http://localhost:8000/health" "Stream Server"
    wait_for_service "http://localhost:3000" "Frontend"
    
    log_success "Tous les services sont démarrés et prêts!"
}

# Fonction pour arrêter tous les services
stop_all_services() {
    log_header "🛑 Arrêt de tous les services Veza..."
    
    stop_service "frontend"
    stop_service "stream-server"
    stop_service "chat-server"
    stop_service "backend-api"
    
    log_success "Tous les services sont arrêtés!"
}

# Fonction pour afficher l'état des services
status_services() {
    log_header "📊 État des services Veza..."
    
    local services=(
        "backend-api:8080:Backend API"
        "chat-server:3001:Chat Server"
        "stream-server:8000:Stream Server"
        "frontend:3000:Frontend"
    )
    
    for service_info in "${services[@]}"; do
        IFS=':' read -r service port name <<< "$service_info"
        
        if port_in_use $port; then
            log_success "$name (port $port) - ✅ Actif"
        else
            log_warning "$name (port $port) - ❌ Inactif"
        fi
    done
}

# Fonction pour afficher les logs
show_logs() {
    local service=$1
    
    if [ -z "$service" ]; then
        log_info "Services disponibles:"
        ls -1 "$LOG_DIR"/*.log 2>/dev/null | sed 's/.*\///' | sed 's/\.log$//' | while read -r log_file; do
            echo "  - $log_file"
        done
        return
    fi
    
    local log_file="$LOG_DIR/${service}.log"
    
    if [ -f "$log_file" ]; then
        log_info "Affichage des logs pour $service..."
        tail -f "$log_file"
    else
        log_error "Fichier de log non trouvé: $log_file"
    fi
}

# Fonction pour exécuter les tests
run_tests() {
    local test_type=${1:-"all"}
    
    log_header "�� Exécution des tests ($test_type)..."
    
    if [ -f "$DEV_ENV_DIR/testing/test-framework.sh" ]; then
        "$DEV_ENV_DIR/testing/test-framework.sh" "$test_type"
    else
        log_error "Framework de tests non trouvé"
        exit 1
    fi
}

# Fonction pour générer une nouvelle feature
generate_feature() {
    local feature_name=$1
    
    if [ -z "$feature_name" ]; then
        log_error "Nom de la feature requis"
        echo "Usage: $0 generate <feature-name>"
        exit 1
    fi
    
    log_header "🎯 Génération de la feature: $feature_name"
    
    if [ -f "$DEV_ENV_DIR/tools/generators/generate-feature.sh" ]; then
        "$DEV_ENV_DIR/tools/generators/generate-feature.sh" "$feature_name"
    else
        log_error "Générateur de feature non trouvé"
        exit 1
    fi
}

# Fonction pour afficher l'aide
show_help() {
    echo -e "${CYAN}"
    echo "╔══════════════════════════════════════════════════════════════╗"
    echo "║                    VEZA DEVELOPMENT ENVIRONMENT            ║"
    echo "║                      Script de Gestion                     ║"
    echo "╚══════════════════════════════════════════════════════════════╝"
    echo -e "${NC}"
    
    echo "Usage: $0 <command> [options]"
    echo ""
    echo "Commands:"
    echo "  start                 Démarrer tous les services"
    echo "  stop                  Arrêter tous les services"
    echo "  restart               Redémarrer tous les services"
    echo "  status                Afficher l'état des services"
    echo "  logs [service]        Afficher les logs d'un service"
    echo "  test [type]           Exécuter les tests (unit|integration|all)"
    echo "  generate <name>       Générer une nouvelle feature"
    echo "  setup                 Configurer l'environnement de développement"
    echo "  help                  Afficher cette aide"
    echo ""
    echo "Examples:"
    echo "  $0 start              # Démarrer tous les services"
    echo "  $0 logs backend-api   # Afficher les logs du backend"
    echo "  $0 test unit          # Exécuter les tests unitaires"
    echo "  $0 generate user-auth # Générer une feature d'authentification"
    echo ""
}

# Fonction principale
main() {
    local command=${1:-"help"}
    
    case $command in
        "start")
            start_all_services
            ;;
        "stop")
            stop_all_services
            ;;
        "restart")
            stop_all_services
            sleep 2
            start_all_services
            ;;
        "status")
            status_services
            ;;
        "logs")
            show_logs "$2"
            ;;
        "test")
            run_tests "$2"
            ;;
        "generate")
            generate_feature "$2"
            ;;
        "setup")
            log_info "Configuration de l'environnement de développement..."
            if [ -f "$DEV_ENV_DIR/scripts/setup-dev-environment.sh" ]; then
                "$DEV_ENV_DIR/scripts/setup-dev-environment.sh"
            else
                log_error "Script de configuration non trouvé"
                exit 1
            fi
            ;;
        "help"|*)
            show_help
            ;;
    esac
}

# Vérification des prérequis
if ! command_exists "go" || ! command_exists "cargo" || ! command_exists "node"; then
    log_error "Prérequis manquants. Exécutez d'abord: $0 setup"
    exit 1
fi

# Exécution
main "$@"
