#!/usr/bin/env nu

# Kubernetes Taskserv Self-Install Script
#
# Queries MCP for settings, generates installer config, and runs unattended installation
# Suitable for: Automated deployment, CI/CD pipelines, infrastructure as code

def main [
    --mcp-url: string = "http://localhost:8084"  # MCP server URL
    --workspace: string = "default"               # Workspace name
    --infra: string = "default"                   # Infrastructure name
    --platform: string = "Docker"                 # Deployment platform
    --domain: string = "localhost"                # Domain/hostname
    --webhook-url: string = ""                    # Webhook URL for notifications
    --config-output: string = ""                  # Save config to file (optional)
    --dry-run                                     # Generate config only, don't install
] {
    print "🔧 Kubernetes Taskserv Self-Install"
    print $"   Workspace: ($workspace)"
    print $"   Infrastructure: ($infra)"
    print $"   Platform: ($platform)"
    print ""

    # Step 1: Query MCP for settings
    print "📡 Querying MCP server for configuration..."
    let mcp_config = try {
        query_mcp_settings $mcp_url $workspace $infra
    } catch {
        print $"❌ Failed to query MCP server at ($mcp_url)"
        print "   Ensure MCP server is running and accessible"
        return 1
    }

    print $"   ✅ Retrieved configuration from MCP"
    print ""

    # Step 2: Resolve dependencies
    print "🔍 Resolving dependencies for Kubernetes..."
    let dependencies = resolve_dependencies $mcp_config

    if ($dependencies | length) > 0 {
        print $"   Dependencies found: ($dependencies | str join ', ')"
    } else {
        print "   No dependencies required"
    }
    print ""

    # Step 3: Generate installer configuration
    print "📝 Generating installer configuration..."
    let installer_config = generate_installer_config $mcp_config $platform $domain $webhook_url $dependencies

    # Save config if requested
    if $config_output != "" {
        $installer_config | save -f $config_output
        print $"   💾 Configuration saved to: ($config_output)"
    }

    print "   ✅ Configuration generated"
    print ""

    # Step 4: Display configuration summary
    print "📋 Configuration Summary:"
    print $"   Platform: ($installer_config.deployment.platform)"
    print $"   Mode: ($installer_config.deployment.mode)"
    print $"   Domain: ($installer_config.deployment.domain)"
    print $"   Services: ($installer_config.deployment.services | length) services"
    print $"   Auto-generate secrets: ($installer_config.deployment.auto_generate_secrets)"

    if ($installer_config.notifications? | is-not-empty) {
        print $"   Notifications: Enabled (($installer_config.notifications.webhook_url))"
    } else {
        print "   Notifications: Disabled"
    }
    print ""

    # Step 5: Run installer in unattended mode
    if $dry_run {
        print "🔍 Dry-run mode - skipping installation"
        print "   To install, run without --dry-run flag"
        return 0
    }

    print "🚀 Starting unattended installation..."
    print ""

    let config_file = $"/tmp/kubernetes-install-(date now | format date '%Y%m%d-%H%M%S').toml"
    $installer_config | save -f $config_file

    try {
        run_unattended_installer $config_file
    } catch {
        print "❌ Installation failed"
        print $"   Config file saved at: ($config_file)"
        return 1
    }

    # Cleanup temp config
    rm -f $config_file

    print ""
    print "🎉 Kubernetes taskserv installed successfully!"
    print ""
    print "Next steps:"
    print "  • Verify installation: kubectl get pods -n provisioning"
    print "  • Check cluster status: provisioning cluster list"
    print "  • Access dashboard: provisioning orchestrator health"
    print ""

    return 0
}

# Query MCP server for configuration settings
def query_mcp_settings [mcp_url: string, workspace: string, infra: string] {
    let response = http get $"($mcp_url)/api/v1/config/($workspace)/($infra)/kubernetes"

    if ($response | is-empty) {
        error make {msg: "Empty response from MCP server"}
    }

    return $response
}

# Resolve taskserv dependencies
def resolve_dependencies [config: record] {
    let required_deps = [
        "containerd"
        "etcd"
    ]

    let optional_deps = [
        "cilium"
        "helm"
    ]

    # Check which dependencies are enabled in config
    let enabled_optional = $optional_deps | filter {|dep|
        ($config.dependencies? | get -i $dep | default false)
    }

    return ($required_deps | append $enabled_optional)
}

# Generate installer configuration from MCP settings
def generate_installer_config [
    mcp_config: record
    platform: string
    domain: string
    webhook_url: string
    dependencies: list
] {
    # Base configuration
    mut config = {
        installation_id: $"kubernetes-($mcp_config.version?)-((date now | format date '%Y%m%d-%H%M%S'))"
        verbose: ($mcp_config.verbose? | default false)
        fail_fast: true
        cleanup_on_failure: true
        provisioning_path: "/usr/local/bin/provisioning"
        work_dir: "~/.provisioning"
        deployment: {
            platform: $platform
            mode: "CICD"
            domain: $domain
            auto_generate_secrets: true
            services: []
        }
        env_vars: {}
    }

    # Add core services
    $config.deployment.services = [
        {
            name: "orchestrator"
            description: "Task coordination engine"
            port: 8080
            enabled: true
            required: true
        }
        {
            name: "control-center"
            description: "Web UI dashboard"
            port: 8081
            enabled: true
            required: true
        }
        {
            name: "coredns"
            description: "DNS service"
            port: 5353
            enabled: true
            required: true
        }
    ]

    # Add Kubernetes-specific services
    $config.deployment.services = ($config.deployment.services | append [
        {
            name: "kubernetes"
            description: "Kubernetes cluster"
            port: 6443
            enabled: true
            required: true
        }
    ])

    # Add dependency services
    for dep in $dependencies {
        let service = match $dep {
            "containerd" => {
                name: "containerd"
                description: "Container runtime"
                port: 0
                enabled: true
                required: true
            }
            "etcd" => {
                name: "etcd"
                description: "Distributed key-value store"
                port: 2379
                enabled: true
                required: true
            }
            "cilium" => {
                name: "cilium"
                description: "Network plugin"
                port: 0
                enabled: true
                required: false
            }
            "helm" => {
                name: "helm"
                description: "Package manager"
                port: 0
                enabled: true
                required: false
            }
            _ => null
        }

        if ($service | is-not-empty) {
            $config.deployment.services = ($config.deployment.services | append [$service])
        }
    }

    # Add webhook notifications if provided
    if $webhook_url != "" {
        $config.notifications = {
            webhook_url: $webhook_url
            notify_progress: true
            notify_completion: true
            notify_failure: true
            retry_attempts: 3
            headers: {
                "Content-Type": "application/json"
            }
        }
    }

    # Add environment variables from MCP config
    if ($mcp_config.env? | is-not-empty) {
        $config.env_vars = $mcp_config.env
    }

    # Add Kubernetes-specific environment variables
    $config.env_vars = ($config.env_vars | merge {
        LOG_LEVEL: "info"
        PROVISIONING_MODE: "kubernetes"
        K8S_VERSION: ($mcp_config.version? | default "1.28.0")
        ENABLE_DEBUG: "false"
    })

    return $config
}

# Run the provisioning installer in unattended mode
def run_unattended_installer [config_file: string] {
    let installer_path = which provisioning-installer | get path.0?

    if ($installer_path | is-empty) {
        error make {msg: "provisioning-installer not found in PATH"}
    }

    print $"   Running: ($installer_path) --unattended --config ($config_file)"
    print ""

    # Run the installer
    let result = run-external $installer_path "--unattended" "--config" $config_file

    return $result
}

# Helper: Generate a sample config for reference
def "main sample" [
    --output: string = "kubernetes-install-sample.toml"  # Output file path
] {
    print $"📝 Generating sample Kubernetes installation config..."

    let sample_config = {
        installation_id: "kubernetes-1.28.0-sample"
        verbose: true
        fail_fast: true
        cleanup_on_failure: true
        provisioning_path: "/usr/local/bin/provisioning"
        work_dir: "~/.provisioning"
        deployment: {
            platform: "Docker"
            mode: "CICD"
            domain: "k8s.local"
            auto_generate_secrets: true
            services: [
                {
                    name: "orchestrator"
                    description: "Task coordination engine"
                    port: 8080
                    enabled: true
                    required: true
                }
                {
                    name: "control-center"
                    description: "Web UI dashboard"
                    port: 8081
                    enabled: true
                    required: true
                }
                {
                    name: "kubernetes"
                    description: "Kubernetes cluster"
                    port: 6443
                    enabled: true
                    required: true
                }
                {
                    name: "containerd"
                    description: "Container runtime"
                    port: 0
                    enabled: true
                    required: true
                }
                {
                    name: "etcd"
                    description: "Distributed key-value store"
                    port: 2379
                    enabled: true
                    required: true
                }
            ]
        }
        notifications: {
            webhook_url: "https://example.com/webhook"
            notify_progress: true
            notify_completion: true
            notify_failure: true
            retry_attempts: 3
            headers: {
                "Content-Type": "application/json"
            }
        }
        env_vars: {
            LOG_LEVEL: "info"
            PROVISIONING_MODE: "kubernetes"
            K8S_VERSION: "1.28.0"
            ENABLE_DEBUG: "false"
        }
    }

    $sample_config | to toml | save -f $output
    print $"   ✅ Sample config saved to: ($output)"
    print ""
    print "Usage:"
    print $"   provisioning-installer --unattended --config ($output)"
    print ""
}
