//! Redis Cluster Deployment Example
//!
//! This example shows how to deploy a Redis cluster using the
//! KubernetesManager convenience methods.

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

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

    // Create the namespace if it doesn't exist
    println!("Creating namespace 'cache' if it doesn't exist...");
    match km.namespace_create("cache").await {
        Ok(_) => println!("✓ Namespace 'cache' created"),
        Err(e) => {
            if e.to_string().contains("already exists") {
                println!("✓ Namespace 'cache' already exists");
            } else {
                return Err(e.into());
            }
        }
    }

    // Clean up any existing resources first
    println!("Cleaning up any existing Redis resources...");
    match km.deployment_delete("redis-cluster").await {
        Ok(_) => println!("✓ Deleted existing deployment"),
        Err(_) => println!("✓ No existing deployment to delete"),
    }

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

    // Configure Redis-specific labels
    let mut labels = HashMap::new();
    labels.insert("app".to_string(), "redis-cluster".to_string());
    labels.insert("type".to_string(), "cache".to_string());
    labels.insert("engine".to_string(), "redis".to_string());

    // Configure Redis environment variables
    let mut env_vars = HashMap::new();
    env_vars.insert("REDIS_PASSWORD".to_string(), "redispassword".to_string());
    env_vars.insert("REDIS_PORT".to_string(), "6379".to_string());
    env_vars.insert("REDIS_DATABASES".to_string(), "16".to_string());
    env_vars.insert("REDIS_MAXMEMORY".to_string(), "256mb".to_string());
    env_vars.insert(
        "REDIS_MAXMEMORY_POLICY".to_string(),
        "allkeys-lru".to_string(),
    );

    // Deploy the Redis cluster using the convenience method
    println!("Deploying Redis cluster...");
    km.deploy_application(
        "redis-cluster",  // name
        "redis:7-alpine", // image
        3,                // replicas (Redis cluster nodes)
        6379,             // port
        Some(labels),     // labels
        Some(env_vars),   // environment variables
    )
    .await?;

    println!("✅ Redis cluster deployed successfully!");

    // Check deployment status
    let deployments = km.deployments_list().await?;
    let redis_deployment = deployments
        .iter()
        .find(|d| d.metadata.name.as_ref() == Some(&"redis-cluster".to_string()));

    if let Some(deployment) = redis_deployment {
        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!(
            "Deployment status: {}/{} replicas ready",
            ready_replicas, total_replicas
        );
    }

    println!("\n📋 Connection Information:");
    println!("  Host: redis-cluster.cache.svc.cluster.local");
    println!("  Port: 6379");
    println!("  Password: Configure REDIS_PASSWORD environment variable");

    println!("\n🔧 To connect from another pod:");
    println!("  redis-cli -h redis-cluster.cache.svc.cluster.local");

    println!("\n💡 Next steps:");
    println!("  • Configure Redis authentication with environment variables");
    println!("  • Set up Redis clustering configuration");
    println!("  • Add persistent volume claims for data persistence");
    println!("  • Configure memory limits and eviction policies");

    Ok(())
}
