#!/bin/bash
# ================================================
# Math Platform - Pre-Deployment Validation
# ================================================

set -e

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

PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
ERRORS=0
WARNINGS=0

echo -e "${BLUE}============================================${NC}"
echo -e "${BLUE}Math Platform - Pre-Deployment Validation${NC}"
echo -e "${BLUE}============================================${NC}"

# Function to print check result
print_result() {
    local status=$1
    local message=$2

    if [ "$status" = "OK" ]; then
        echo -e "${GREEN}✓${NC} $message"
    elif [ "$status" = "WARN" ]; then
        echo -e "${YELLOW}⚠${NC} $message"
        WARNINGS=$((WARNINGS + 1))
    else
        echo -e "${RED}✗${NC} $message"
        ERRORS=$((ERRORS + 1))
    fi
}

# Check 1: Docker Installation
echo -e "\n${BLUE}Checking Prerequisites${NC}"
echo "----------------------------------------"

if command -v docker &> /dev/null; then
    DOCKER_VERSION=$(docker --version | awk '{print $3}' | sed 's/,//')
    print_result "OK" "Docker installed: $DOCKER_VERSION"
else
    print_result "FAIL" "Docker not installed"
fi

if command -v docker-compose &> /dev/null || docker compose version &> /dev/null; then
    print_result "OK" "Docker Compose available"
else
    print_result "FAIL" "Docker Compose not installed"
fi

# Check 2: Environment File
echo -e "\n${BLUE}Checking Environment Configuration${NC}"
echo "----------------------------------------"

if [ -f "$PROJECT_ROOT/.env" ]; then
    print_result "OK" ".env file exists"

    # Check critical variables
    source "$PROJECT_ROOT/.env"

    if [ -n "$DB_PASSWORD" ] && [ ${#DB_PASSWORD} -ge 16 ]; then
        print_result "OK" "DB_PASSWORD configured (length: ${#DB_PASSWORD})"
    else
        print_result "WARN" "DB_PASSWORD not set or too short (min 16 chars)"
    fi

    if [ -n "$REDIS_PASSWORD" ] && [ ${#REDIS_PASSWORD} -ge 16 ]; then
        print_result "OK" "REDIS_PASSWORD configured (length: ${#REDIS_PASSWORD})"
    else
        print_result "WARN" "REDIS_PASSWORD not set or too short (min 16 chars)"
    fi

    if [ -n "$JWT_SECRET" ] && [ ${#JWT_SECRET} -ge 32 ]; then
        print_result "OK" "JWT_SECRET configured (length: ${#JWT_SECRET})"
    else
        print_result "FAIL" "JWT_SECRET not set or too short (min 32 chars)"
    fi

    if [ -n "$AI_API_KEY" ]; then
        print_result "OK" "AI_API_KEY configured"
    else
        print_result "WARN" "AI_API_KEY not set (AI features won't work)"
    fi
else
    print_result "FAIL" ".env file not found"
fi

# Check 3: Required Files
echo -e "\n${BLUE}Checking Required Files${NC}"
echo "----------------------------------------"

files=(
    "docker-compose.yml:docker-compose.yml"
    "Dockerfile (Backend):docker/Dockerfile.backend"
    "Dockerfile (Frontend):docker/Dockerfile.frontend"
    "Dockerfile (Worker):docker/Dockerfile.worker"
    "Nginx config:docker/nginx.conf"
    "Backend package.json:backend/package.json"
    "Frontend package.json:frontend/package.json"
    "Prisma schema:backend/prisma/schema.prisma"
    "Next.js config:frontend/next.config.js"
)

for file_info in "${files[@]}"; do
    file="${file_info##*:}"
    name="${file_info%:*}"

    if [ -f "$PROJECT_ROOT/$file" ]; then
        print_result "OK" "$name exists"
    else
        print_result "FAIL" "$name missing: $file"
    fi
done

# Check 4: Required Directories
echo -e "\n${BLUE}Checking Directories${NC}"
echo "----------------------------------------"

dirs=(
    "Backend source:backend/src"
    "Frontend source:frontend/src"
    "Docker data:docker/data"
    "Docker logs:docker/logs"
    "Init scripts:docker/init-scripts"
    "Scripts:scripts"
    "PDF storage:pdfs"
)

for dir_info in "${dirs[@]}"; do
    dir="${dir_info##*:}"
    name="${dir_info%:*}"

    if [ -d "$PROJECT_ROOT/$dir" ]; then
        print_result "OK" "$name exists"
    else
        print_result "WARN" "$name missing: $dir"
    fi
done

# Check 5: Script Permissions
echo -e "\n${BLUE}Checking Script Permissions${NC}"
echo "----------------------------------------"

scripts=(
    "docker/start.sh"
    "docker/stop.sh"
    "docker/backup.sh"
    "scripts/test-e2e.sh"
    "scripts/health-check.sh"
    "scripts/monitor.sh"
)

for script in "${scripts[@]}"; do
    if [ -f "$PROJECT_ROOT/$script" ]; then
        if [ -x "$PROJECT_ROOT/$script" ]; then
            print_result "OK" "$script is executable"
        else
            print_result "WARN" "$script is not executable"
        fi
    else
        print_result "WARN" "$script not found"
    fi
done

# Check 6: Docker Resources
echo -e "\n${BLUE}Checking Docker Resources${NC}"
echo "----------------------------------------"

if docker info &> /dev/null; then
    # Check available disk space
    DISK_AVAILABLE=$(df -h "$PROJECT_ROOT" | awk 'NR==2 {print $4}')
    DISK_USAGE_PERCENT=$(df -h "$PROJECT_ROOT" | awk 'NR==2 {print $5}' | sed 's/%//')

    if [ "$DISK_USAGE_PERCENT" -lt 80 ]; then
        print_result "OK" "Disk space available: $DISK_AVAILABLE"
    else
        print_result "WARN" "Disk space low: $DISK_AVAILABLE available"
    fi

    # Check Docker memory
    DOCKER_MEMORY=$(docker info 2>/dev/null | grep "Total Memory" | awk '{print $3}' || echo "N/A")
    if [ "$DOCKER_MEMORY" != "N/A" ]; then
        print_result "OK" "Docker memory: $DOCKER_MEMORY"
    fi

    # Check for running containers
    RUNNING_CONTAINERS=$(docker ps -q | wc -l)
    print_result "OK" "Running containers: $RUNNING_CONTAINERS"
else
    print_result "WARN" "Docker not running"
fi

# Check 7: Port Availability
echo -e "\n${BLUE}Checking Port Availability${NC}"
echo "----------------------------------------"

ports=("80:HTTP" "3000:Frontend" "3001:Backend" "5432:PostgreSQL" "6379:Redis")

for port_info in "${ports[@]}"; do
    port="${port_info%%:*}"
    name="${port_info##*:}"

    if netstat -tuln 2>/dev/null | grep -q ":$port " || ss -tuln 2>/dev/null | grep -q ":$port "; then
        print_result "WARN" "Port $port ($name) already in use"
    else
        print_result "OK" "Port $port ($name) available"
    fi
done

# Check 8: File Permissions
echo -e "\n${BLUE}Checking File Permissions${NC}"
echo "----------------------------------------"

if [ -d "$PROJECT_ROOT/docker/data" ]; then
    if [ -w "$PROJECT_ROOT/docker/data" ]; then
        print_result "OK" "docker/data is writable"
    else
        print_result "FAIL" "docker/data is not writable"
    fi
fi

if [ -d "$PROJECT_ROOT/docker/logs" ]; then
    if [ -w "$PROJECT_ROOT/docker/logs" ]; then
        print_result "OK" "docker/logs is writable"
    else
        print_result "FAIL" "docker/logs is not writable"
    fi
fi

# Summary
echo -e "\n${BLUE}============================================${NC}"
echo -e "${BLUE}Validation Summary${NC}"
echo -e "${BLUE}============================================${NC}"

if [ $ERRORS -eq 0 ] && [ $WARNINGS -eq 0 ]; then
    echo -e "${GREEN}All checks passed! Ready for deployment.${NC}\n"
    exit 0
elif [ $ERRORS -eq 0 ]; then
    echo -e "${YELLOW}Validation passed with $WARNINGS warning(s).${NC}\n"
    exit 0
else
    echo -e "${RED}Validation failed with $ERRORS error(s) and $WARNINGS warning(s).${NC}\n"
    exit 1
fi
