#!/bin/bash

# Script de test global pour la plateforme Veza
# Usage: ./scripts/run-tests.sh [service] [--coverage] [--verbose]

set -e

# Couleurs pour l'affichage
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Variables
COVERAGE=false
VERBOSE=false
SERVICE=""
TOTAL_TESTS=0
PASSED_TESTS=0
FAILED_TESTS=0

# Fonction d'aide
show_help() {
    echo "Usage: $0 [service] [options]"
    echo ""
    echo "Services:"
    echo "  chat       - Tests du serveur de chat Rust"
    echo "  stream     - Tests du serveur de streaming Rust"
    echo "  api        - Tests de l'API Go"
    echo "  web        - Tests du frontend web"
    echo "  all        - Tous les services (défaut)"
    echo ""
    echo "Options:"
    echo "  --coverage - Activer la couverture de code"
    echo "  --verbose  - Affichage détaillé"
    echo "  --help     - Afficher cette aide"
    echo ""
    echo "Exemples:"
    echo "  $0                    # Tous les tests"
    echo "  $0 chat --coverage    # Tests chat avec couverture"
    echo "  $0 api --verbose      # Tests API en mode verbeux"
}

# Fonction de logging
log() {
    echo -e "${BLUE}[$(date +'%H:%M:%S')]${NC} $1"
}

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

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

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

# Fonction pour exécuter les tests Rust
run_rust_tests() {
    local service=$1
    local project_dir="veza-${service}-server"
    
    log "Exécution des tests Rust pour $service..."
    
    cd "$project_dir" || exit 1
    
    # Tests smoke
    log "Tests smoke..."
    if cargo test --test smoke_tests --quiet; then
        log_success "Tests smoke $service réussis"
        ((PASSED_TESTS++))
    else
        log_error "Tests smoke $service échoués"
        ((FAILED_TESTS++))
        return 1
    fi
    
    # Tests unitaires
    log "Tests unitaires..."
    if cargo test --test unit_tests --quiet; then
        log_success "Tests unitaires $service réussis"
        ((PASSED_TESTS++))
    else
        log_error "Tests unitaires $service échoués"
        ((FAILED_TESTS++))
        return 1
    fi
    
    # Tests d'intégration
    log "Tests d'intégration..."
    if cargo test --test integration_tests --quiet; then
        log_success "Tests d'intégration $service réussis"
        ((PASSED_TESTS++))
    else
        log_error "Tests d'intégration $service échoués"
        ((FAILED_TESTS++))
        return 1
    fi
    
    # Couverture si demandée
    if [ "$COVERAGE" = true ]; then
        log "Génération de la couverture de code..."
        if command -v cargo-tarpaulin &> /dev/null; then
            cargo tarpaulin --out Html --output-dir ../coverage/$service
            log_success "Couverture générée dans coverage/$service"
        else
            log_warning "cargo-tarpaulin non installé, couverture ignorée"
        fi
    fi
    
    cd ..
    ((TOTAL_TESTS += 3))
}

# Fonction pour exécuter les tests Go
run_go_tests() {
    local project_dir="veza-backend-api"
    
    log "Exécution des tests Go..."
    
    cd "$project_dir" || exit 1
    
    # Tests avec couverture
    local coverage_flags=""
    if [ "$COVERAGE" = true ]; then
        coverage_flags="-coverprofile=coverage.out -covermode=atomic"
    fi
    
    if go test ./... $coverage_flags -v=$VERBOSE; then
        log_success "Tests Go réussis"
        ((PASSED_TESTS++))
        
        if [ "$COVERAGE" = true ]; then
            # Générer le rapport de couverture
            go tool cover -html=coverage.out -o ../coverage/api/coverage.html
            local coverage_percent=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
            log_success "Couverture Go: ${coverage_percent}%"
            
            # Vérifier le seuil de couverture
            if (( $(echo "$coverage_percent >= 60" | bc -l) )); then
                log_success "Seuil de couverture atteint (≥60%)"
            else
                log_warning "Couverture insuffisante (${coverage_percent}% < 60%)"
            fi
        fi
    else
        log_error "Tests Go échoués"
        ((FAILED_TESTS++))
        return 1
    fi
    
    cd ..
    ((TOTAL_TESTS++))
}

# Fonction pour exécuter les tests Web
run_web_tests() {
    local project_dir="apps/web"
    
    log "Exécution des tests Web..."
    
    cd "$project_dir" || exit 1
    
    # Installation des dépendances si nécessaire
    if [ ! -d "node_modules" ]; then
        log "Installation des dépendances..."
        npm ci
    fi
    
    # Tests unitaires
    local test_command="npm run test"
    if [ "$COVERAGE" = true ]; then
        test_command="npm run test -- --coverage"
    fi
    
    if [ "$VERBOSE" = true ]; then
        test_command="$test_command --reporter=verbose"
    fi
    
    if eval $test_command; then
        log_success "Tests Web réussis"
        ((PASSED_TESTS++))
    else
        log_error "Tests Web échoués"
        ((FAILED_TESTS++))
        return 1
    fi
    
    # Tests E2E si disponibles
    if [ -f "playwright.config.ts" ]; then
        log "Exécution des tests E2E..."
        if npm run test:e2e; then
            log_success "Tests E2E réussis"
            ((PASSED_TESTS++))
        else
            log_warning "Tests E2E échoués (non bloquant)"
        fi
        ((TOTAL_TESTS++))
    fi
    
    cd ../..
    ((TOTAL_TESTS++))
}

# Fonction pour créer le répertoire de couverture
setup_coverage() {
    if [ "$COVERAGE" = true ]; then
        mkdir -p coverage/{chat,stream,api,web}
        log "Répertoire de couverture créé"
    fi
}

# Fonction pour afficher le résumé
show_summary() {
    echo ""
    echo "=========================================="
    echo "RÉSUMÉ DES TESTS"
    echo "=========================================="
    echo "Total des suites de tests: $TOTAL_TESTS"
    echo -e "Réussies: ${GREEN}$PASSED_TESTS${NC}"
    echo -e "Échouées: ${RED}$FAILED_TESTS${NC}"
    
    if [ "$COVERAGE" = true ]; then
        echo ""
        echo "Rapports de couverture disponibles dans:"
        echo "  - coverage/chat/    (Rust Chat Server)"
        echo "  - coverage/stream/  (Rust Stream Server)"
        echo "  - coverage/api/     (Go API)"
        echo "  - coverage/web/     (Web Frontend)"
    fi
    
    if [ $FAILED_TESTS -eq 0 ]; then
        log_success "Tous les tests sont passés !"
        exit 0
    else
        log_error "$FAILED_TESTS suite(s) de tests ont échoué"
        exit 1
    fi
}

# Parsing des arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        --coverage)
            COVERAGE=true
            shift
            ;;
        --verbose)
            VERBOSE=true
            shift
            ;;
        --help)
            show_help
            exit 0
            ;;
        chat|stream|api|web|all)
            SERVICE=$1
            shift
            ;;
        *)
            log_error "Argument inconnu: $1"
            show_help
            exit 1
            ;;
    esac
done

# Service par défaut
if [ -z "$SERVICE" ]; then
    SERVICE="all"
fi

# Vérification des prérequis
if ! command -v cargo &> /dev/null && [[ "$SERVICE" =~ ^(chat|stream|all)$ ]]; then
    log_error "Cargo n'est pas installé"
    exit 1
fi

if ! command -v go &> /dev/null && [[ "$SERVICE" =~ ^(api|all)$ ]]; then
    log_error "Go n'est pas installé"
    exit 1
fi

if ! command -v npm &> /dev/null && [[ "$SERVICE" =~ ^(web|all)$ ]]; then
    log_error "npm n'est pas installé"
    exit 1
fi

# Début des tests
echo "🧪 Démarrage des tests Veza Platform"
echo "Service: $SERVICE"
echo "Couverture: $COVERAGE"
echo "Verbeux: $VERBOSE"
echo ""

setup_coverage

# Exécution des tests selon le service
case $SERVICE in
    chat)
        run_rust_tests "chat"
        ;;
    stream)
        run_rust_tests "stream"
        ;;
    api)
        run_go_tests
        ;;
    web)
        run_web_tests
        ;;
    all)
        run_rust_tests "chat"
        run_rust_tests "stream"
        run_go_tests
        run_web_tests
        ;;
esac

show_summary
