#!/usr/bin/env nu

# API Server management for Provisioning System
# Provides HTTP REST API endpoints for infrastructure management

use ../api/server.nu *
use ../api/routes.nu *
use ../lib_provisioning/utils/settings.nu *

export def "main api" [
    command?: string           # Command: start, stop, status, docs
    --port (-p): int = 8080    # Port to run the API server on
    --host: string = "localhost"  # Host to bind the server to
    --enable-websocket         # Enable WebSocket support for real-time updates
    --enable-cors              # Enable CORS for cross-origin requests
    --debug (-d)               # Enable debug mode
    --background (-b)          # Run server in background
    --config-file: string      # Custom configuration file path
    --ssl                      # Enable SSL/TLS (requires certificates)
    --cert-file: string        # SSL certificate file path
    --key-file: string         # SSL private key file path
    --doc-format: string = "markdown"  # Documentation format (markdown, json, yaml)
]: nothing -> nothing {

    let cmd = $command | default "start"

    match $cmd {
        "start" => {
            print $"🚀 Starting Provisioning API Server..."

            # Validate configuration
            let config_valid = validate_api_config --port $port --host $host
            if not $config_valid.valid {
                error make {
                    msg: $"Invalid configuration: ($config_valid.errors | str join ', ')"
                    help: "Please check your configuration and try again"
                }
            }

            # Check dependencies
            check_api_dependencies

            # Start the server
            if $background {
                start_api_background --port $port --host $host --enable-websocket $enable_websocket --enable-cors $enable_cors --debug $debug
            } else {
                start_api_server --port $port --host $host --enable-websocket $enable_websocket --enable-cors $enable_cors --debug $debug
            }
        }

        "stop" => {
            print "🛑 Stopping API server..."
            stop_api_server --port $port --host $host
        }

        "status" => {
            print "🔍 Checking API server status..."
            let health = check_api_health --port $port --host $host
            print ($health | table)
        }

        "docs" => {
            print "📚 Generating API documentation..."
            generate_api_documentation --format $doc_format
        }

        "routes" => {
            print "🗺️  Listing API routes..."
            let routes = get_route_definitions
            print ($routes | select method path description | table)
        }

        "validate" => {
            print "✅ Validating API configuration..."
            let validation = validate_routes
            print ($validation | table)
        }

        "spec" => {
            print "📋 Generating OpenAPI specification..."
            let spec = generate_api_spec
            print ($spec | to json)
        }

        _ => {
            print_api_help
        }
    }
}

def validate_api_config [
    --port: int
    --host: string
]: nothing -> record {
    mut errors = []
    mut valid = true

    # Validate port range
    if $port < 1024 or $port > 65535 {
        $errors = ($errors | append "Port must be between 1024 and 65535")
        $valid = false
    }

    # Validate host format
    if ($host | str contains " ") {
        $errors = ($errors | append "Host cannot contain spaces")
        $valid = false
    }

    # Check if port is available
    if $valid {
        let port_available = (do -i {
            http listen $port --host $host --timeout 1 | ignore
            false
        } | default true)

        if not $port_available {
            $errors = ($errors | append $"Port ($port) is already in use")
            $valid = false
        }
    }

    {
        valid: $valid
        errors: $errors
        port: $port
        host: $host
    }
}

def check_api_dependencies []: nothing -> nothing {
    print "🔍 Checking dependencies..."

    # Check Python availability
    let python_available = (do -i { python3 --version } | complete | get exit_code) == 0
    if not $python_available {
        error make {
            msg: "Python 3 is required for the API server"
            help: "Please install Python 3 and ensure it's available in PATH"
        }
    }

    # Check required environment variables
    if ($env.PROVISIONING_PATH? | is-empty) {
        print "⚠️  Warning: PROVISIONING_PATH not set, using current directory"
        $env.PROVISIONING_PATH = (pwd)
    }

    print "✅ All dependencies satisfied"
}

def start_api_background [
    --port: int
    --host: string
    --enable-websocket
    --enable-cors
    --debug
]: nothing -> nothing {
    print $"🚀 Starting API server in background on ($host):($port)..."

    # Create background process
    let server_cmd = $"nu -c 'use ($env.PWD)/core/nulib/api/server.nu; start_api_server --port ($port) --host ($host)'"

    if $enable_websocket {
        $server_cmd = $server_cmd + " --enable-websocket"
    }
    if $enable_cors {
        $server_cmd = $server_cmd + " --enable-cors"
    }
    if $debug {
        $server_cmd = $server_cmd + " --debug"
    }

    # Save PID for later management
    let pid_file = $"/tmp/provisioning-api-($port).pid"

    bash -c $"($server_cmd) & echo $! > ($pid_file)"

    sleep 2sec
    let health = check_api_health --port $port --host $host

    if $health.api_server {
        print $"✅ API server started successfully in background"
        print $"📍 PID file: ($pid_file)"
        print $"🌐 URL: http://($host):($port)"
    } else {
        print "❌ Failed to start API server"
    }
}

def stop_api_server [
    --port: int
    --host: string
]: nothing -> nothing {
    let pid_file = $"/tmp/provisioning-api-($port).pid"

    if ($pid_file | path exists) {
        let pid = (open $pid_file | str trim)
        print $"🛑 Stopping API server (PID: ($pid))..."

        try {
            kill $pid
            rm -f $pid_file
            print "✅ API server stopped successfully"
        } catch {
            print "⚠️  Failed to stop server, trying force kill..."
            kill -9 $pid
            rm -f $pid_file
            print "✅ Server force stopped"
        }
    } else {
        print "⚠️  No running API server found on port ($port)"

        # Try to find and kill any Python processes running the API
        let python_pids = (ps | where name =~ "python3" and command =~ "provisioning_api_server" | get pid)

        if ($python_pids | length) > 0 {
            print $"🔍 Found ($python_pids | length) related processes, stopping them..."
            $python_pids | each { |pid| kill $pid }
            print "✅ Related processes stopped"
        }
    }
}

def generate_api_documentation [
    --format: string = "markdown"
]: nothing -> nothing {
    let output_file = match $format {
        "markdown" => "api_documentation.md"
        "json" => "api_spec.json"
        "yaml" => "api_spec.yaml"
        _ => "api_documentation.md"
    }

    match $format {
        "markdown" => {
            let docs = generate_route_docs
            $docs | save --force $output_file
            print $"📚 Markdown documentation saved to: ($output_file)"
        }

        "json" => {
            let spec = generate_api_spec
            $spec | to json | save --force $output_file
            print $"📋 OpenAPI JSON spec saved to: ($output_file)"
        }

        "yaml" => {
            let spec = generate_api_spec
            $spec | to yaml | save --force $output_file
            print $"📋 OpenAPI YAML spec saved to: ($output_file)"
        }

        _ => {
            print $"❌ Unsupported format: ($format)"
            print "Supported formats: markdown, json, yaml"
        }
    }
}

def print_api_help []: nothing -> nothing {
    print "
🚀 Provisioning API Server Management

USAGE:
    provisioning api [COMMAND] [OPTIONS]

COMMANDS:
    start       Start the API server (default)
    stop        Stop the API server
    status      Check server status
    docs        Generate API documentation
    routes      List all available routes
    validate    Validate API configuration
    spec        Generate OpenAPI specification

OPTIONS:
    -p, --port <PORT>          Port to run server on [default: 8080]
    --host <HOST>              Host to bind to [default: localhost]
    --enable-websocket         Enable WebSocket support
    --enable-cors              Enable CORS headers
    -d, --debug                Enable debug mode
    -b, --background           Run in background
    --doc-format <FORMAT>      Documentation format [default: markdown]

EXAMPLES:
    # Start server on default port
    provisioning api start

    # Start on custom port with debugging
    provisioning api start --port 9090 --debug

    # Start in background with WebSocket support
    provisioning api start --background --enable-websocket

    # Generate API documentation
    provisioning api docs --doc-format json

    # Check server status
    provisioning api status

    # Stop running server
    provisioning api stop

ENDPOINTS:
    GET  /api/v1/health              Health check
    GET  /api/v1/query               Query infrastructure
    POST /api/v1/query               Complex queries
    GET  /api/v1/metrics             System metrics
    GET  /api/v1/logs                System logs
    GET  /api/v1/dashboard           Dashboard data
    GET  /api/v1/servers             List servers
    POST /api/v1/servers             Create server
    GET  /api/v1/ai/query            AI-powered queries

For more information, visit: https://docs.provisioning.dev/api
"
}