#!/usr/bin/env herodo
// Pre-flight check: Ensure Kubernetes cluster is accessible
try {
    if !run("kubectl cluster-info").execute().success {
        print("SKIPPED: Kubernetes cluster is not accessible");
        exit(0);
    }
} catch(e) {
    print("SKIPPED: Kubernetes cluster is not accessible: " + e);
    exit(0);
}

// kube_mcp_install.rhai
// Demonstrates building a Kubernetes MCP Server image inside Kubernetes using KubeBuilder
// This is a conversion of the bash script installers/kube_mcp_install.sh to Rhai
// Extended to deploy a local registry, build the image, push it, and deploy the MCP server

println("===========================================");
println("  Kubernetes MCP Server Image Builder");
println("  with Local Registry & Deployment");
println("===========================================");
println("");

// Configuration
let config = #{
    namespace: "build",
    builder_name: "mcp-builder",
    base_image: "ubuntu:24.04",
    final_image: "kubernetes-mcp-server",
    final_tag: "latest",
    port: 7777,
    log_level: 9,
    cpu: "2",
    memory: "4Gi",
    // Registry configuration
    registry_name: "local-registry",
    registry_port: 30500,
    registry_username: "admin",
    registry_password: "secretpass123",
    // Deployment configuration
    deploy_replicas: 1
};

println(`Configuration:`);
println(`  Namespace: ${config.namespace}`);
println(`  Builder: ${config.builder_name}`);
println(`  Base image: ${config.base_image}`);
println(`  Target image: ${config.final_image}:${config.final_tag}`);
println(`  Registry: ${config.registry_name} (port ${config.registry_port})`);
println("");

// Step 0: Create namespace and deploy local registry
println("==> Step 0: Setting up namespace and local registry");

let km = kubernetes(config.namespace);
km.create_namespace(config.namespace);
println(`Namespace '${config.namespace}' ready`);

// Deploy a local Docker registry with authentication
let registry_config = #{
    name: config.registry_name,
    namespace: config.namespace,
    node_port: config.registry_port,
    username: config.registry_username,
    password: config.registry_password,
    reset: false  // Set to true to redeploy
};

println(`Deploying local registry '${config.registry_name}'...`);
let registry = deploy_registry_with_config(km, registry_config);

println(`Registry deployed successfully!`);
println(`  Internal endpoint: ${registry.endpoint}:${registry.port}`);
println(`  External endpoint: ${registry.external_endpoint}`);
println(`  Auth enabled: ${registry.auth_enabled}`);
if registry.auth_enabled {
    println(`  Username: ${registry.username}`);
    println(`  Auth secret: ${registry.auth_secret_name}`);
    println(`  Pull secret: ${registry.pull_secret_name}`);
}
println("");

// Build the full image name with registry prefix
let registry_image = `${registry.endpoint}:${registry.port}/${config.final_image}:${config.final_tag}`;
let external_registry_image = `localhost:${config.registry_port}/${config.final_image}:${config.final_tag}`;
println(`Target image: ${registry_image}`);
println("");

// Step 1: Create and provision the build machine
println("==> Step 1: Provisioning build machine in Kubernetes");

let machine = kube_build_machine(config.namespace, config.builder_name);
machine.image = config.base_image;
machine.cpu = config.cpu;
machine.memory = config.memory;
machine.debug_mode = true;

println(`Creating builder pod '${config.builder_name}' in namespace '${config.namespace}'...`);
let handle = provision(machine);
println(`Builder pod ready: ${handle.pod_name}`);
println("");

// Step 2: Detect architecture
println("==> Step 2: Detecting architecture");
let arch_result = exec(handle, ["uname", "-m"]);
let arch = arch_result.stdout.trim();
let arch_name = if arch == "x86_64" || arch == "amd64" {
    "amd64"
} else if arch == "aarch64" || arch == "arm64" {
    "arm64"
} else {
    throw `Unsupported architecture: ${arch}`;
};
println(`Architecture: ${arch} -> ${arch_name}`);
println("");

// Step 3: Install dependencies in build container
println("==> Step 3: Installing dependencies");
let deps_result = exec(handle, ["apt-get", "update"]);
if !deps_result.success {
    println(`Warning: apt-get update failed: ${deps_result.stderr}`);
}

let install_result = exec(handle, ["apt-get", "install", "-y", "curl", "ca-certificates"]);
if !install_result.success {
    throw `Failed to install dependencies: ${install_result.stderr}`;
}
println("Dependencies installed: curl, ca-certificates");
println("");

// Step 4: Get latest version from GitHub
println("==> Step 4: Getting latest version");
// Note: In a real scenario, you would fetch this from the GitHub API
// For this example, we'll use a placeholder version
let version = "v0.3.1"; // This would normally be fetched dynamically
println(`Using version: ${version}`);
println("");

// Step 5: Download kubernetes-mcp-server binary
println("==> Step 5: Downloading kubernetes-mcp-server");
let download_url = `https://github.com/containers/kubernetes-mcp-server/releases/download/${version}/kubernetes-mcp-server-linux-${arch_name}`;
println(`Download URL: ${download_url}`);

let download_cmd = `curl -fsSL -o /usr/local/bin/kubernetes-mcp-server "${download_url}"`;
let download_result = exec(handle, ["sh", "-c", download_cmd]);
if !download_result.success {
    throw `Failed to download: ${download_result.stderr}`;
}

let chmod_result = exec(handle, ["chmod", "+x", "/usr/local/bin/kubernetes-mcp-server"]);
if !chmod_result.success {
    throw `Failed to set executable: ${chmod_result.stderr}`;
}
println("Binary downloaded and made executable");
println("");

// Step 6: Verify installation
println("==> Step 6: Verifying installation");
let verify_result = exec(handle, ["/usr/local/bin/kubernetes-mcp-server", "--version"]);
if verify_result.success {
    println(`Version: ${verify_result.stdout.trim()}`);
} else {
    println(`Warning: Could not verify version: ${verify_result.stderr}`);
}
println("");

// Step 7: Build the container image using the fluent kube_bah() API
println("==> Step 7: Building container image with fluent buildah API");

// Use the new fluent kube_bah() API for building container images
// This creates a Bah builder that runs buildah commands in the Kubernetes pod
// Use the registry-prefixed image name so we can push directly

let image = kube_bah(handle, "mcp-build", config.base_image)
    .copy("/usr/local/bin/kubernetes-mcp-server", "/usr/local/bin/kubernetes-mcp-server")
    .set_entrypoint("/usr/local/bin/kubernetes-mcp-server")
    .set_cmd(`--port ${config.port} --log-level ${config.log_level}`)
    .commit(registry_image);

if !image.success {
    throw `Failed to build image: ${image.stderr}`;
}
println(`Image built and committed: ${registry_image}`);
println(`Container ID: ${image.container_id}`);
println("");

// Step 8: List images to verify
println("==> Step 8: Verifying image");
let bah_images = buildah(handle, ["images"]);
println("Available images:");
println(bah_images.stdout);

// Step 9: Push image to local registry
println("==> Step 9: Pushing image to local registry");

// Login to the registry if auth is enabled
if registry.auth_enabled {
    println(`Logging into registry...`);
    let login_result = buildah(handle, [
        "login",
        "--tls-verify=false",
        "-u", config.registry_username,
        "-p", config.registry_password,
        `${registry.endpoint}:${registry.port}`
    ]);
    if !login_result.success {
        println(`Warning: Login failed (may work anyway): ${login_result.stderr}`);
    } else {
        println("Login successful");
    }
}

// Push to the registry
println(`Pushing ${registry_image} to registry...`);
let push_result = buildah(handle, [
    "push",
    "--tls-verify=false",
    registry_image,
    `docker://${registry_image}`
]);

if !push_result.success {
    println(`Warning: Push may have failed: ${push_result.stderr}`);
} else {
    println(`Image pushed successfully to: ${registry_image}`);
}
println("");

// Step 10: Cleanup buildah container
println("==> Step 10: Cleaning up buildah container");
image.remove();
println("Buildah container removed");
println("");

// Step 11: Destroy the build machine
println("==> Step 11: Destroying build machine");
destroy(handle);
println("Build machine destroyed");
println("");

// Step 12: Deploy the MCP Server to Kubernetes
println("==> Step 12: Deploying MCP Server to Kubernetes");

let deploy_namespace = "mcp-server";
let deploy_km = kubernetes(deploy_namespace);
deploy_km.create_namespace(deploy_namespace);
println(`Created namespace: ${deploy_namespace}`);

// Create deployment labels
let labels = #{
    "app": "kubernetes-mcp-server",
    "component": "mcp"
};

// Create environment variables
let env_vars = #{
    "MCP_PORT": `${config.port}`,
    "LOG_LEVEL": `${config.log_level}`
};

// Deploy the application
println(`Deploying ${config.final_image} with ${config.deploy_replicas} replica(s)...`);
deploy_km.deploy_application(
    "kubernetes-mcp-server",
    registry_image,
    config.deploy_replicas,
    config.port,
    labels,
    env_vars
);

println("MCP Server deployed!");
println("");

// Get service connection info
let svc_info = deploy_km.service_connection_info("kubernetes-mcp-server");
println(`Service endpoint: ${svc_info.connection_string()}`);
println("");

println("===========================================");
println("  Build & Deploy Complete!");
println("===========================================");
println("");
println(`Image: ${registry_image}`);
println(`Registry: ${registry.endpoint}:${registry.port}`);
println(`Deployment: kubernetes-mcp-server in ${deploy_namespace}`);
println("");
println("Internal access (from within cluster):");
println(`  URL: http://${svc_info.connection_string()}/sse`);
println("");
println("To access from outside the cluster, create an Ingress or use port-forward:");
println(`  kubectl port-forward -n ${deploy_namespace} svc/kubernetes-mcp-server ${config.port}:${config.port}`);
println("");
println("MCP Client Configuration:");
println("  {");
println(`    "mcpServers": {`);
println(`      "kubernetes": {`);
println(`        "url": "http://localhost:${config.port}/sse"`);
println("      }");
println("    }");
println("  }");
println("");

// Optional: Show how to clean up everything
println("To clean up:");
println(`  - Delete MCP server: kubectl delete namespace ${deploy_namespace}`);
println(`  - Delete registry: kubectl delete namespace ${config.namespace}`);
println("");

`Build and deploy completed successfully: ${registry_image}`
