#!/usr/bin/env bash
# Local Development Environment Deployment Script
# This script deploys a basic local development environment

set -euo pipefail

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

# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SETTINGS_FILE="${SCRIPT_DIR}/settings.ncl"
CONFIG_FILE="${SCRIPT_DIR}/config.toml"
CHECK_MODE=false

# Function to print colored output
print_status() {
    local color=$1
    local message=$2
    echo -e "${color}${message}${NC}"
}

print_step() {
    print_status $BLUE "🔄 $1"
}

print_success() {
    print_status $GREEN "✅ $1"
}

print_warning() {
    print_status $YELLOW "⚠️  $1"
}

print_error() {
    print_status $RED "❌ $1"
}

# Function to check if provisioning command is available
check_provisioning() {
    if ! command -v provisioning &> /dev/null; then
        print_error "Provisioning command not found. Please install provisioning first."
        exit 1
    fi
    print_success "Provisioning available"
}

# Function to validate configuration
validate_config() {
    print_step "Validating configuration..."

    if ! provisioning validate config --settings "$SETTINGS_FILE"; then
        print_error "Configuration validation failed"
        exit 1
    fi

    print_success "Configuration validation passed"
}

# Function to check prerequisites
check_prerequisites() {
    print_step "Checking prerequisites..."

    # Check if Docker is available (for local provider)
    if command -v docker &> /dev/null; then
        if ! docker ps &> /dev/null; then
            print_warning "Docker is installed but not running. Some local provider features may not work."
        else
            print_success "Docker is available and running"
        fi
    else
        print_warning "Docker not found. Local provider will use alternative methods."
    fi

    # Check available disk space (need at least 5GB)
    available_space=$(df "$SCRIPT_DIR" | tail -1 | awk '{print $4}')
    required_space=$((5 * 1024 * 1024))  # 5GB in KB

    if [ "$available_space" -lt "$required_space" ]; then
        print_error "Insufficient disk space. Need at least 5GB, have $((available_space / 1024 / 1024))GB"
        exit 1
    fi

    print_success "Prerequisites check passed"
}

# Function to deploy servers
deploy_servers() {
    print_step "Deploying servers..."

    local cmd_args=(
        "server" "create"
        "--settings" "$SETTINGS_FILE"
    )

    if [ "$CHECK_MODE" = true ]; then
        cmd_args+=("--check")
        print_step "Running in check mode (dry run)"
    fi

    if ! provisioning "${cmd_args[@]}"; then
        print_error "Server deployment failed"
        exit 1
    fi

    if [ "$CHECK_MODE" = false ]; then
        print_success "Servers deployed successfully"

        # Wait for servers to be ready
        print_step "Waiting for servers to be ready..."
        sleep 10  # Give servers time to initialize

        # Verify servers are running
        provisioning server list --settings "$SETTINGS_FILE"
    else
        print_success "Server deployment plan validated"
    fi
}

# Function to install task services
install_services() {
    if [ "$CHECK_MODE" = true ]; then
        print_step "Skipping service installation in check mode"
        return
    fi

    print_step "Installing task services..."

    # Install container runtime first (dependency for other services)
    print_step "Installing containerd..."
    if ! provisioning taskserv create containerd --settings "$SETTINGS_FILE" --yes; then
        print_warning "Containerd installation failed, continuing..."
    else
        print_success "Containerd installed"
    fi

    # Install Nginx on web server
    print_step "Installing Nginx on web server..."
    if ! provisioning taskserv create nginx --servers web-dev-01 --settings "$SETTINGS_FILE" --yes; then
        print_warning "Nginx installation failed, continuing..."
    else
        print_success "Nginx installed on web-dev-01"
    fi

    # Install PostgreSQL on database server
    print_step "Installing PostgreSQL on database server..."
    if ! provisioning taskserv create postgresql --servers db-dev-01 --settings "$SETTINGS_FILE" --yes; then
        print_warning "PostgreSQL installation failed, continuing..."
    else
        print_success "PostgreSQL installed on db-dev-01"
    fi

    # Install Redis on database server
    print_step "Installing Redis on database server..."
    if ! provisioning taskserv create redis --servers db-dev-01 --settings "$SETTINGS_FILE" --yes; then
        print_warning "Redis installation failed, continuing..."
    else
        print_success "Redis installed on db-dev-01"
    fi

    # Install Node.js on web server
    print_step "Installing Node.js on web server..."
    if ! provisioning taskserv create nodejs --servers web-dev-01 --settings "$SETTINGS_FILE" --yes; then
        print_warning "Node.js installation failed, continuing..."
    else
        print_success "Node.js installed on web-dev-01"
    fi

    print_success "Task services installation completed"
}

# Function to verify deployment
verify_deployment() {
    if [ "$CHECK_MODE" = true ]; then
        print_step "Skipping verification in check mode"
        return
    fi

    print_step "Verifying deployment..."

    # Check server status
    print_step "Checking server status..."
    provisioning server list --settings "$SETTINGS_FILE"

    # Check installed services
    print_step "Checking installed services..."
    provisioning taskserv list --settings "$SETTINGS_FILE" --installed

    # Try to SSH to servers
    print_step "Testing SSH connectivity..."
    if provisioning server ssh web-dev-01 --settings "$SETTINGS_FILE" --command "echo 'Web server SSH OK'" 2>/dev/null; then
        print_success "SSH to web-dev-01 working"
    else
        print_warning "SSH to web-dev-01 failed"
    fi

    if provisioning server ssh db-dev-01 --settings "$SETTINGS_FILE" --command "echo 'Database server SSH OK'" 2>/dev/null; then
        print_success "SSH to db-dev-01 working"
    else
        print_warning "SSH to db-dev-01 failed"
    fi

    print_success "Deployment verification completed"
}

# Function to show usage information
show_usage() {
    cat << EOF
Local Development Environment Deployment Script

Usage: $0 [OPTIONS]

OPTIONS:
    --check, -c     Run in check mode (dry run, show what would be deployed)
    --help, -h      Show this help message

EXAMPLES:
    $0                    Deploy the development environment
    $0 --check            See what would be deployed without making changes
    $0 -c                 Same as --check

ENVIRONMENT:
    PROVISIONING_DEBUG=true    Enable debug output
    PROVISIONING_ENV=dev       Set environment (already set to dev for this example)

FILES:
    settings.ncl      Infrastructure definition
    config.toml     Environment configuration
    deploy.sh       This deployment script
    verify.sh       Verification script
    cleanup.sh      Cleanup script

For more information, see README.md
EOF
}

# Function to show post-deployment information
show_post_deployment_info() {
    if [ "$CHECK_MODE" = true ]; then
        return
    fi

    print_success "Local Development Environment Deployment Complete!"
    echo
    print_status $BLUE "📋 What was created:"
    echo "   • web-dev-01: Web development server (192.168.100.10)"
    echo "   • db-dev-01:  Database server (192.168.100.11)"
    echo
    print_status $BLUE "🔧 Installed services:"
    echo "   • Nginx web server (port 80)"
    echo "   • PostgreSQL database (port 5432)"
    echo "   • Redis cache (port 6379)"
    echo "   • Node.js runtime"
    echo "   • Container runtime (containerd)"
    echo
    print_status $BLUE "🚀 Next steps:"
    echo "   • SSH to servers: provisioning server ssh web-dev-01 --settings settings.ncl"
    echo "   • Verify deployment: ./verify.sh"
    echo "   • Start developing your application"
    echo "   • When done, clean up: ./cleanup.sh"
    echo
    print_status $BLUE "📚 Learn more:"
    echo "   • Read README.md for detailed usage"
    echo "   • Try other examples in ../../"
    echo "   • Check the troubleshooting guide if you have issues"
    echo
}

# Main deployment function
main() {
    local start_time=$(date +%s)

    print_status $BLUE "🚀 Local Development Environment Deployment"
    print_status $BLUE "=============================================="
    echo

    # Parse command line arguments
    while [[ $# -gt 0 ]]; do
        case $1 in
            --check|-c)
                CHECK_MODE=true
                shift
                ;;
            --help|-h)
                show_usage
                exit 0
                ;;
            *)
                print_error "Unknown option: $1"
                show_usage
                exit 1
                ;;
        esac
    done

    # Set environment variable
    export PROVISIONING_ENV=development

    # Run deployment steps
    check_provisioning
    check_prerequisites
    validate_config
    deploy_servers
    install_services
    verify_deployment

    local end_time=$(date +%s)
    local duration=$((end_time - start_time))

    echo
    print_success "Deployment completed in ${duration} seconds"
    show_post_deployment_info
}

# Error handling
trap 'print_error "Deployment failed. Check the output above for details."; exit 1' ERR

# Run main function
main "$@"
