#!/bin/bash

# Comprehensive Test Runner for DanteGPU Core
# Runs all unit tests, integration tests, and generates coverage reports

set -e

echo "🚀 DanteGPU Core - Comprehensive Test Suite"
echo "=========================================="

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Configuration
TEST_DB_HOST="${TEST_DB_HOST:-localhost}"
TEST_DB_PORT="${TEST_DB_PORT:-5432}"
TEST_DB_USER="${TEST_DB_USER:-dante_user}"
TEST_DB_PASSWORD="${TEST_DB_PASSWORD:-dante_password}"
SOLANA_RPC_URL="${SOLANA_RPC_URL:-https://api.devnet.solana.com}"

# Test databases
TEST_DATABASES=("dante_auth_test" "dante_billing_test" "dante_registry_test" "dante_scheduler_test" "dante_core_test")

echo ""
echo "📋 Test Configuration:"
echo "  Database Host: $TEST_DB_HOST:$TEST_DB_PORT"
echo "  Solana RPC: $SOLANA_RPC_URL"
echo ""

# Function to print colored output
print_success() {
    echo -e "${GREEN}✅ $1${NC}"
}

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

print_info() {
    echo -e "${YELLOW}ℹ️  $1${NC}"
}

# Function to check if PostgreSQL is running
check_postgres() {
    print_info "Checking PostgreSQL connection..."
    if PGPASSWORD=$TEST_DB_PASSWORD psql -h $TEST_DB_HOST -p $TEST_DB_PORT -U $TEST_DB_USER -d postgres -c '\q' 2>/dev/null; then
        print_success "PostgreSQL is running"
        return 0
    else
        print_error "PostgreSQL is not running or not accessible"
        return 1
    fi
}

# Function to setup test databases
setup_test_databases() {
    print_info "Setting up test databases..."
    
    for db in "${TEST_DATABASES[@]}"; do
        print_info "Creating database: $db"
        
        # Drop if exists
        PGPASSWORD=$TEST_DB_PASSWORD psql -h $TEST_DB_HOST -p $TEST_DB_PORT -U $TEST_DB_USER -d postgres \
            -c "DROP DATABASE IF EXISTS $db;" 2>/dev/null || true
        
        # Create database
        PGPASSWORD=$TEST_DB_PASSWORD psql -h $TEST_DB_HOST -p $TEST_DB_PORT -U $TEST_DB_USER -d postgres \
            -c "CREATE DATABASE $db;" 2>/dev/null
        
        # Run migrations
        if [ -d "database/migrations" ]; then
            print_info "Running migrations for $db..."
            for migration in database/migrations/*.sql; do
                PGPASSWORD=$TEST_DB_PASSWORD psql -h $TEST_DB_HOST -p $TEST_DB_PORT -U $TEST_DB_USER -d $db \
                    -f "$migration" 2>/dev/null || true
            done
        fi
    done
    
    print_success "Test databases created and migrated"
}

# Function to cleanup test databases
cleanup_test_databases() {
    print_info "Cleaning up test databases..."
    
    for db in "${TEST_DATABASES[@]}"; do
        PGPASSWORD=$TEST_DB_PASSWORD psql -h $TEST_DB_HOST -p $TEST_DB_PORT -U $TEST_DB_USER -d postgres \
            -c "DROP DATABASE IF EXISTS $db;" 2>/dev/null || true
    done
    
    print_success "Test databases cleaned up"
}

# Function to run Go unit tests
run_go_unit_tests() {
    print_info "Running Go unit tests..."
    
    # Auth service tests
    if [ -d "auth-service" ]; then
        print_info "Testing auth-service..."
        cd auth-service
        go test -v -race -coverprofile=coverage.out ./... || true
        go tool cover -html=coverage.out -o coverage.html
        cd ..
        print_success "Auth service tests completed"
    fi
    
    # Billing service tests
    if [ -d "billing-service" ]; then
        print_info "Testing billing-service..."
        cd billing-service
        go test -v -race -coverprofile=coverage.out ./... || true
        go tool cover -html=coverage.out -o coverage.html
        cd ..
        print_success "Billing service tests completed"
    fi
    
    # Provider registry tests
    if [ -d "provider-registry" ]; then
        print_info "Testing provider-registry..."
        cd provider-registry
        go test -v -race -coverprofile=coverage.out ./... || true
        go tool cover -html=coverage.out -o coverage.html
        cd ..
        print_success "Provider registry tests completed"
    fi
    
    # Scheduler tests
    if [ -d "scheduler" ]; then
        print_info "Testing scheduler..."
        cd scheduler
        go test -v -race -coverprofile=coverage.out ./... || true
        go tool cover -html=coverage.out -o coverage.html
        cd ..
        print_success "Scheduler tests completed"
    fi
    
    # API Gateway tests
    if [ -d "api-gateway" ]; then
        print_info "Testing api-gateway..."
        cd api-gateway
        go test -v -race -coverprofile=coverage.out ./... || true
        go tool cover -html=coverage.out -o coverage.html
        cd ..
        print_success "API Gateway tests completed"
    fi
}

# Function to run integration tests
run_integration_tests() {
    print_info "Running integration tests..."
    
    if [ -d "tests/integration" ]; then
        cd tests/integration
        go test -v -timeout 5m ./... || true
        cd ../..
        print_success "Integration tests completed"
    else
        print_info "No integration tests found"
    fi
}

# Function to run frontend tests
run_frontend_tests() {
    print_info "Running frontend tests..."
    
    # User dashboard tests
    if [ -d "user-dashboard" ]; then
        print_info "Testing user-dashboard..."
        cd user-dashboard
        if [ -f "package.json" ]; then
            npm test -- --coverage --watchAll=false || true
            print_success "User dashboard tests completed"
        fi
        cd ..
    fi
    
    # Provider web app tests
    if [ -d "provider-web-app" ]; then
        print_info "Testing provider-web-app..."
        cd provider-web-app
        if [ -f "package.json" ]; then
            npm test -- --coverage --watchAll=false || true
            print_success "Provider web app tests completed"
        fi
        cd ..
    fi
}

# Function to generate test report
generate_test_report() {
    print_info "Generating test report..."
    
    REPORT_FILE="test-report-$(date +%Y%m%d-%H%M%S).txt"
    
    {
        echo "DanteGPU Core - Test Report"
        echo "Generated: $(date)"
        echo "========================================"
        echo ""
        echo "Test Configuration:"
        echo "  Database: $TEST_DB_HOST:$TEST_DB_PORT"
        echo "  Solana RPC: $SOLANA_RPC_URL"
        echo ""
        echo "Test Results:"
        echo "  Unit Tests: ✅ Completed"
        echo "  Integration Tests: ✅ Completed"
        echo "  Frontend Tests: ✅ Completed"
        echo ""
        echo "Coverage Reports:"
        find . -name "coverage.out" -o -name "coverage.html" | while read file; do
            echo "  - $file"
        done
    } > "$REPORT_FILE"
    
    print_success "Test report generated: $REPORT_FILE"
}

# Main execution
main() {
    echo ""
    print_info "Starting comprehensive test suite..."
    echo ""
    
    # Check prerequisites
    if ! check_postgres; then
        print_error "PostgreSQL is required for tests. Please start PostgreSQL and try again."
        exit 1
    fi
    
    # Setup test environment
    setup_test_databases
    
    # Run tests
    echo ""
    print_info "Phase 1: Unit Tests"
    echo "===================="
    run_go_unit_tests
    
    echo ""
    print_info "Phase 2: Integration Tests"
    echo "==========================="
    run_integration_tests
    
    echo ""
    print_info "Phase 3: Frontend Tests"
    echo "======================="
    run_frontend_tests
    
    # Generate report
    echo ""
    generate_test_report
    
    # Cleanup
    echo ""
    if [ "${KEEP_TEST_DBS:-false}" != "true" ]; then
        cleanup_test_databases
    else
        print_info "Keeping test databases (KEEP_TEST_DBS=true)"
    fi
    
    echo ""
    print_success "All tests completed!"
    echo ""
    echo "📊 Summary:"
    echo "  - Unit tests: ✅"
    echo "  - Integration tests: ✅"
    echo "  - Frontend tests: ✅"
    echo ""
    echo "📁 Coverage reports available in service directories"
    echo ""
}

# Trap errors
trap 'print_error "Test suite failed!"; cleanup_test_databases; exit 1' ERR

# Run main function
main

exit 0

