#!/bin/bash
set -e

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

# 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 a service is healthy
check_service_health() {
    local service=$1
    local max_retries=30
    local retry=0

    print_info "Waiting for $service to be healthy..."

    while [ $retry -lt $max_retries ]; do
        if docker compose ps --format json $service 2>/dev/null | grep -q '"Health":"healthy"'; then
            print_success "$service is healthy"
            return 0
        elif docker compose ps --format json $service 2>/dev/null | grep -q '"State":"running"'; then
            # Service is running but no health check defined
            print_success "$service is running"
            return 0
        fi

        retry=$((retry + 1))
        sleep 2
    done

    print_error "$service failed to become healthy"
    return 1
}

# Function to check HTTP endpoint
check_http_endpoint() {
    local url=$1
    local service_name=$2
    local max_retries=15
    local retry=0

    print_info "Checking $service_name endpoint: $url"

    while [ $retry -lt $max_retries ]; do
        if curl -sf "$url" > /dev/null 2>&1; then
            print_success "$service_name endpoint is accessible"
            return 0
        fi

        retry=$((retry + 1))
        sleep 2
    done

    print_error "$service_name endpoint is not accessible"
    return 1
}

# Main test script
main() {
    echo "=================================================="
    echo "  Mosaic Stack Docker Deployment Test"
    echo "=================================================="
    echo ""

    # Check if Docker is running
    print_info "Checking Docker..."
    if ! docker info > /dev/null 2>&1; then
        print_error "Docker is not running"
        exit 1
    fi
    print_success "Docker is running"

    # Check if docker-compose.yml exists
    if [ ! -f "docker-compose.yml" ]; then
        print_error "docker-compose.yml not found"
        exit 1
    fi
    print_success "docker-compose.yml found"

    # Check if .env exists, create from .env.example if not
    if [ ! -f ".env" ]; then
        print_info ".env not found, copying from .env.example"
        cp .env.example .env
        print_success ".env created from .env.example"
    fi

    # Clean up any existing containers
    print_info "Cleaning up existing containers..."
    docker compose down -v > /dev/null 2>&1 || true
    print_success "Cleanup complete"

    echo ""
    echo "Starting core services..."
    echo ""

    # Start core services (no profiles)
    print_info "Starting PostgreSQL, Valkey, API, and Web..."
    docker compose up -d

    # Wait a bit for services to initialize
    sleep 5

    # Check PostgreSQL
    check_service_health "postgres" || exit 1

    # Check Valkey
    check_service_health "valkey" || exit 1

    # Check API
    check_service_health "api" || exit 1

    # Check Web
    check_service_health "web" || exit 1

    echo ""
    echo "Checking service endpoints..."
    echo ""

    # Check API health endpoint
    check_http_endpoint "http://localhost:3001/health" "API" || exit 1

    # Check Web
    check_http_endpoint "http://localhost:3000" "Web" || exit 1

    echo ""
    echo "Checking service connectivity..."
    echo ""

    # Check PostgreSQL connectivity from API
    print_info "Testing PostgreSQL connection from API..."
    if docker compose exec -T api sh -c 'nc -zv postgres 5432' > /dev/null 2>&1; then
        print_success "API can connect to PostgreSQL"
    else
        print_error "API cannot connect to PostgreSQL"
        exit 1
    fi

    # Check Valkey connectivity from API
    print_info "Testing Valkey connection from API..."
    if docker compose exec -T api sh -c 'nc -zv valkey 6379' > /dev/null 2>&1; then
        print_success "API can connect to Valkey"
    else
        print_error "API cannot connect to Valkey"
        exit 1
    fi

    echo ""
    echo "Checking Docker resources..."
    echo ""

    # Check volumes
    print_info "Verifying volumes..."
    if docker volume ls | grep -q "mosaic-postgres-data"; then
        print_success "PostgreSQL volume created"
    else
        print_error "PostgreSQL volume missing"
        exit 1
    fi

    if docker volume ls | grep -q "mosaic-valkey-data"; then
        print_success "Valkey volume created"
    else
        print_error "Valkey volume missing"
        exit 1
    fi

    # Check networks
    print_info "Verifying networks..."
    if docker network ls | grep -q "mosaic-internal"; then
        print_success "Internal network created"
    else
        print_error "Internal network missing"
        exit 1
    fi

    if docker network ls | grep -q "mosaic-public"; then
        print_success "Public network created"
    else
        print_error "Public network missing"
        exit 1
    fi

    echo ""
    echo "=================================================="
    print_success "All tests passed!"
    echo "=================================================="
    echo ""
    echo "Services are running:"
    echo "  - Web:        http://localhost:3000"
    echo "  - API:        http://localhost:3001"
    echo "  - API Health: http://localhost:3001/health"
    echo "  - PostgreSQL: localhost:5432"
    echo "  - Valkey:     localhost:6379"
    echo ""
    echo "To view logs:"
    echo "  docker compose logs -f"
    echo ""
    echo "To stop services:"
    echo "  docker compose down"
    echo ""
    echo "To stop and remove volumes:"
    echo "  docker compose down -v"
    echo ""
}

# Run main function
main
