#!/usr/bin/env nu

# Port Manager - Centralized port configuration management
# Manages all platform service ports from a single source of truth

const PORTS_CONFIG = "/Users/Akasha/project-provisioning/provisioning/config/ports.toml"

# Show current port status
export def main [] {
    print "🔧 Provisioning Platform Port Manager\n"
    print "Usage:"
    print "  port-manager check      - Check which ports are in use"
    print "  port-manager list       - List all configured ports"
    print "  port-manager update     - Update ports from config file"
    print "  port-manager conflicts  - Show port conflicts"
    print ""
}

# Check port availability
export def "main check" [] {
    print "🔍 Checking port availability\n"

    let ports = load_ports_config

    for port in ($ports | transpose service config) {
        let port_num = $port.config.port
        let service_name = $port.service

        try {
            let check = (^lsof -i $":($port_num)" | complete)

            if $check.exit_code == 0 {
                let lines = ($check.stdout | lines)
                if ($lines | length) > 1 {
                    let process_line = ($lines | get 1 | split row -r '\s+')
                    let process_name = ($process_line | get 0)
                    let pid = ($process_line | get 1)

                    print $"  ⚠️  ($service_name | fill -a r -w 20): Port ($port_num) IN USE by ($process_name) \(PID: ($pid)\)"
                } else {
                    print $"  ✅  ($service_name | fill -a r -w 20): Port ($port_num) available"
                }
            } else {
                print $"  ✅  ($service_name | fill -a r -w 20): Port ($port_num) available"
            }
        } catch {
            print $"  ✅  ($service_name | fill -a r -w 20): Port ($port_num) available"
        }
    }
}

# List all configured ports
export def "main list" [] {
    print "📋 Configured Ports\n"

    let ports = load_ports_config

    print $"╭────────────────────────┬──────┬──────────────────────────────╮"
    print $"│ Service                │ Port │ Description                  │"
    print $"├────────────────────────┼──────┼──────────────────────────────┤"

    for port in ($ports | transpose service config) {
        let service = ($port.service | fill -a r -w 22)
        let port_num = ($port.config.port | into string | fill -a r -w 4)
        let desc = ($port.config.description | str substring 0..28 | fill -a r -w 28)

        print $"│ ($service) │ ($port_num) │ ($desc) │"
    }

    print $"╰────────────────────────┴──────┴──────────────────────────────╯"
}

# Show port conflicts
export def "main conflicts" [] {
    print "⚠️  Checking for port conflicts\n"

    let ports = load_ports_config
    let conflicts = []

    for port in ($ports | transpose service config) {
        let port_num = $port.config.port

        try {
            let check = (^lsof -i $":($port_num)" | complete)

            if $check.exit_code == 0 {
                let lines = ($check.stdout | lines)
                if ($lines | length) > 1 {
                    let process_line = ($lines | get 1 | split row -r '\s+')
                    let process_name = ($process_line | get 0)
                    let pid = ($process_line | get 1)

                    print $"  🔴 ($port.service): Port ($port_num) is used by ($process_name) \(PID: ($pid)\)"
                }
            }
        } catch {
            # Port is free
        }
    }

    print "\n💡 To free a port, stop the conflicting process or change the service port"
}

# Update service ports from configuration
export def "main update" [
    service?: string  # Service to update (optional, updates all if not provided)
    --dry-run         # Show what would be changed without applying
] {
    let ports = load_ports_config

    if $service != null {
        if $service not-in ($ports | columns) {
            error make {msg: $"Service '($service)' not found in configuration"}
        }

        print $"📝 Updating ($service)..."
        update_service_port $service ($ports | get $service | get port) $dry_run
    } else {
        print "📝 Updating all services...\n"

        for svc in ($ports | transpose service config) {
            update_service_port $svc.service $svc.config.port $dry_run
        }
    }

    if $dry_run {
        print "\n💡 Run without --dry-run to apply changes"
    } else {
        print "\n✅ Update complete. Remember to rebuild and restart services!"
    }
}

# Helper: Load ports configuration
def load_ports_config [] {
    if not ($PORTS_CONFIG | path exists) {
        # Return defaults if config doesn't exist
        return {
            orchestrator: {port: 9090, description: "Workflow orchestration engine"},
            control_center: {port: 9080, description: "Auth & authorization service"},
            api_gateway: {port: 9083, description: "Unified API gateway"},
            mcp_server: {port: 9082, description: "Model Context Protocol server"},
            oci_registry: {port: 5000, description: "OCI registry"},
            coredns: {port: 5353, description: "Internal DNS server"},
            gitea: {port: 3000, description: "Git server"},
            frontend: {port: 3001, description: "Web UI"},
            surrealdb: {port: 8000, description: "Main database"},
            redis: {port: 6379, description: "Cache"},
            postgresql: {port: 5432, description: "Optional database"}
        }
    }

    open $PORTS_CONFIG
}

# Helper: Update a single service port
def update_service_port [service: string, port: int, dry_run: bool] {
    print $"  Updating ($service) to port ($port)..."

    # This would update config files, Rust code, etc.
    # For now, just show what would be done
    if $dry_run {
        print $"    Would update configuration files for ($service)"
        print $"    Would update Rust defaults"
        print $"    Would update documentation"
    } else {
        print $"    ⚠️  Automated updates not yet implemented"
        print $"    Please update manually:"
        print $"      1. Update code defaults"
        print $"      2. Update config files"
        print $"      3. Rebuild service"
    }
}
