//! Generic Application Deployment Example
//!
//! This example shows how to deploy any containerized application using the
//! KubernetesManager convenience methods. This works for any Docker image.

use herolib_system::kubernetes::KubernetesManager;
use std::collections::HashMap;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create Kubernetes manager
    let km = KubernetesManager::new("default").await?;

    // Clean up any existing resources first
    println!("=== Cleaning up existing resources ===");
    let apps_to_clean = ["web-server", "node-app", "mongodb"];

    for app in &apps_to_clean {
        match km.deployment_delete(app).await {
            Ok(_) => println!("✓ Deleted existing deployment: {}", app),
            Err(_) => println!("✓ No existing deployment to delete: {}", app),
        }

        match km.service_delete(app).await {
            Ok(_) => println!("✓ Deleted existing service: {}", app),
            Err(_) => println!("✓ No existing service to delete: {}", app),
        }
    }

    // Example 1: Simple web server deployment
    println!("\n=== Example 1: Simple Nginx Web Server ===");

    km.deploy_application("web-server", "nginx:latest", 2, 80, None, None)
        .await?;
    println!("✅ Nginx web server deployed!");

    // Example 2: Node.js application with labels
    println!("\n=== Example 2: Node.js Application ===");

    let mut node_labels = HashMap::new();
    node_labels.insert("app".to_string(), "node-app".to_string());
    node_labels.insert("tier".to_string(), "backend".to_string());
    node_labels.insert("environment".to_string(), "production".to_string());

    // Configure Node.js environment variables
    let mut node_env_vars = HashMap::new();
    node_env_vars.insert("NODE_ENV".to_string(), "production".to_string());
    node_env_vars.insert("PORT".to_string(), "3000".to_string());
    node_env_vars.insert("LOG_LEVEL".to_string(), "info".to_string());
    node_env_vars.insert("MAX_CONNECTIONS".to_string(), "1000".to_string());

    km.deploy_application(
        "node-app",          // name
        "node:18-alpine",    // image
        3,                   // replicas - scale to 3 instances
        3000,                // port
        Some(node_labels),   // labels
        Some(node_env_vars), // environment variables
    )
    .await?;

    println!("✅ Node.js application deployed!");

    // Example 3: Database deployment (any database)
    println!("\n=== Example 3: MongoDB Database ===");

    let mut mongo_labels = HashMap::new();
    mongo_labels.insert("app".to_string(), "mongodb".to_string());
    mongo_labels.insert("type".to_string(), "database".to_string());
    mongo_labels.insert("engine".to_string(), "mongodb".to_string());

    // Configure MongoDB environment variables
    let mut mongo_env_vars = HashMap::new();
    mongo_env_vars.insert(
        "MONGO_INITDB_ROOT_USERNAME".to_string(),
        "admin".to_string(),
    );
    mongo_env_vars.insert(
        "MONGO_INITDB_ROOT_PASSWORD".to_string(),
        "mongopassword".to_string(),
    );
    mongo_env_vars.insert("MONGO_INITDB_DATABASE".to_string(), "myapp".to_string());

    km.deploy_application(
        "mongodb",            // name
        "mongo:6.0",          // image
        1,                    // replicas - single instance for simplicity
        27017,                // port
        Some(mongo_labels),   // labels
        Some(mongo_env_vars), // environment variables
    )
    .await?;

    println!("✅ MongoDB deployed!");

    // Check status of all deployments
    println!("\n=== Checking Deployment Status ===");

    let deployments = km.deployments_list().await?;

    for deployment in &deployments {
        if let Some(name) = &deployment.metadata.name {
            let total_replicas = deployment
                .spec
                .as_ref()
                .and_then(|s| s.replicas)
                .unwrap_or(0);
            let ready_replicas = deployment
                .status
                .as_ref()
                .and_then(|s| s.ready_replicas)
                .unwrap_or(0);

            println!(
                "{}: {}/{} replicas ready",
                name, ready_replicas, total_replicas
            );
        }
    }

    println!("\n🎉 All deployments completed!");
    println!("\n💡 Key Points:");
    println!("  • Any Docker image can be deployed using this simple interface");
    println!("  • Use labels to organize and identify your applications");
    println!(
        "  • The same method works for databases, web servers, APIs, and any containerized app"
    );
    println!("  • For advanced configuration, use the individual KubernetesManager methods");
    println!(
        "  • Environment variables and resource limits can be added via direct Kubernetes API"
    );

    Ok(())
}
