//! Declarative cluster reconciliation example
//!
//! This example demonstrates how to use the reconciliation feature to declaratively
//! manage cluster state. The library will automatically add or remove workers to match
//! the desired configuration.
//!
//! Run with:
//! ```bash
//! cargo run --example declarative_reconciliation
//! ```

use lmrc_k3s::{DesiredClusterConfig, K3sManager, WorkerConfig};

#[tokio::main]
async fn main() -> Result<(), lmrc_k3s::K3sError> {
    // Initialize tracing for logs
    tracing_subscriber::fmt::init();

    // Create a K3s manager
    let manager = K3sManager::builder()
        .version("v1.28.5+k3s1")
        .token("my-secure-cluster-token")
        .disable(vec!["traefik".to_string()])
        .build();

    println!("=== Declarative Cluster Reconciliation Example ===\n");

    // Define the desired cluster state
    let mut desired = DesiredClusterConfig {
        master_ip: "192.168.1.10".to_string(),
        master_private_ip: None,
        workers: vec![
            WorkerConfig::new("192.168.1.11".to_string()),
            WorkerConfig::new("192.168.1.12".to_string()),
        ],
        k3s_version: "v1.28.5+k3s1".to_string(),
        token: "my-secure-cluster-token".to_string(),
        disabled_components: vec!["traefik".to_string()],
    };

    println!("Step 1: Initial cluster setup");
    println!("Desired state: 1 master + 2 workers\n");

    // Create reconciliation plan
    let plan = manager.plan_reconciliation(&desired).await?;
    println!("Reconciliation plan: {}", plan.summary());

    if plan.has_changes() {
        println!("Applying reconciliation...\n");
        manager.reconcile(&desired).await?;
    }

    // Display cluster state
    if let Some(state) = manager.get_cluster_state() {
        println!("✓ Cluster state after reconciliation:");
        println!("  Master: {}", state.master_ip);
        println!("  Workers: {}", state.workers.len());
        println!("  Status: {:?}\n", state.status);
    }

    // === Scenario 2: Scale up - add a new worker ===
    println!("Step 2: Scaling up - adding worker .13");
    desired
        .workers
        .push(WorkerConfig::new("192.168.1.13".to_string()));

    let plan = manager.plan_reconciliation(&desired).await?;
    println!("Reconciliation plan: {}", plan.summary());

    if plan.has_changes() {
        println!("Applying reconciliation...\n");
        manager.reconcile(&desired).await?;
    }

    // Display updated state
    if let Some(state) = manager.get_cluster_state() {
        println!("✓ Cluster state after scaling up:");
        println!("  Workers: {}", state.workers.len());
        for worker in &state.workers {
            println!("    - {} ({:?})", worker.ip, worker.status);
        }
        println!();
    }

    // === Scenario 3: Scale down - remove a worker ===
    println!("Step 3: Scaling down - removing worker .12");
    desired.workers.retain(|w| w.ip != "192.168.1.12");

    let plan = manager.plan_reconciliation(&desired).await?;
    println!("Reconciliation plan: {}", plan.summary());

    if plan.has_changes() {
        println!("This will:");
        println!("  1. Drain the node (move pods to other workers)");
        println!("  2. Delete node from Kubernetes cluster");
        println!("  3. Uninstall K3s from the worker");
        println!("\nApplying reconciliation...\n");
        manager.reconcile(&desired).await?;
    }

    // Display final state
    if let Some(state) = manager.get_cluster_state() {
        println!("✓ Final cluster state:");
        println!("  Master: {}", state.master_ip);
        println!("  Workers: {}", state.workers.len());
        println!("  Ready workers: {}", state.ready_workers_count());
        println!("  Status: {:?}\n", state.status);
    }

    println!("=== Reconciliation Complete ===");
    println!("\nKey benefits of declarative reconciliation:");
    println!("  • Define desired state, not imperative commands");
    println!("  • Idempotent - safe to run multiple times");
    println!("  • Automatically handles add/remove operations");
    println!("  • Graceful node removal with draining");

    Ok(())
}
