//! Docker Registry Deployment Example
//!
//! This example demonstrates how to deploy and manage a Docker Registry
//! on Kubernetes with various configurations.
//!
//! # Usage
//!
//! ```bash
//! cargo run --example 02_registry_deployment --features kubernetes
//! ```
//!
//! # What This Example Does
//!
//! 1. Creates a dedicated namespace for the registry
//! 2. Deploys a simple registry without authentication
//! 3. Verifies registry deployment and retrieves connection info
//! 4. Deploys a registry with authentication
//! 5. Cleans up resources

use herolib_virt::kubernetes::{KubernetesManager, RegistryConfigBuilder};

/// Helper function to print section headers
fn print_section(title: &str) {
    println!("\n=====================================");
    println!("  {}", title);
    println!("=====================================\n");
}

/// Helper function to print test results
fn print_test(test_num: usize, description: &str, passed: bool) {
    let status = if passed { "✓ PASS" } else { "✗ FAIL" };
    println!("Test {}: {} ... {}", test_num, description, status);
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    print_section("Docker Registry Deployment Example");

    println!("This example demonstrates deploying a Docker Registry on Kubernetes");
    println!("and verifying its connectivity and configuration.\n");

    // Create a manager for the registry namespace
    let km = KubernetesManager::new("registry").await?;
    println!("✓ Connected to Kubernetes cluster");
    println!("  Operating on namespace: {}\n", km.namespace());

    // Test 1: Create namespace
    print_section("Test 1: Create Registry Namespace");
    km.namespace_create("registry").await?;
    print_test(1, "Namespace creation", true);

    // Test 2: Deploy simple registry without authentication
    print_section("Test 2: Deploy Simple Registry");
    println!("Deploying registry without authentication...");
    
    let config = RegistryConfigBuilder::new("simple-registry")
        .node_port(30500)
        .timeout_secs(120)
        .reset(true)
        .build();
    
    let result = km.deploy_registry("simple-registry", config).await?;
    print_test(2, "Registry deployment", true);
    println!("  Registry Name: {}", result.name);
    println!("  Namespace: {}", result.namespace);
    println!("  Port: {}", result.port);
    println!("  Node Port: {:?}", result.node_port);

    // Test 3: Verify registry is ready
    print_section("Test 3: Verify Registry Readiness");
    let pods = km.pods_list().await?;
    let registry_pod = pods.iter().find(|p| {
        p.metadata
            .name
            .as_ref()
            .map(|n| n.contains("simple-registry"))
            .unwrap_or(false)
    });

    let registry_ready = registry_pod.is_some();
    print_test(3, "Registry pod exists", registry_ready);

    if let Some(pod) = registry_pod {
        println!("  Pod Name: {:?}", pod.metadata.name);
        println!("  Phase: {:?}", pod.status.as_ref().and_then(|s| s.phase.clone()));
    }

    // Test 4: Verify connection string
    print_section("Test 4: Verify Connection String");
    let connection_str = result.connection_string();
    let has_connection_str = !connection_str.is_empty();
    print_test(4, "Connection string generation", has_connection_str);
    println!("  Internal Connection: {}", connection_str);
    
    if let Some(external) = result.external_connection_string() {
        println!("  External Connection: {}", external);
    }

    // Test 5: Verify image prefix
    print_section("Test 5: Verify Image Prefix");
    let image_prefix = result.image_prefix();
    let has_image_prefix = !image_prefix.is_empty();
    print_test(5, "Image prefix generation", has_image_prefix);
    println!("  Image Prefix: {}", image_prefix);

    // Test 6: Check resource counts
    print_section("Test 6: Check Resource Counts");
    let counts = km.resource_counts().await?;
    println!("  Pods: {}", counts.get("pods").unwrap_or(&0));
    println!("  Services: {}", counts.get("services").unwrap_or(&0));
    println!("  Deployments: {}", counts.get("deployments").unwrap_or(&0));
    
    let has_resources = counts.get("pods").unwrap_or(&0) > &0;
    print_test(6, "Resources created", has_resources);

    // Test 7: Verify deployment exists
    print_section("Test 7: Verify Deployment");
    let deployments = km.deployments_list().await?;
    let registry_deployment = deployments.iter().find(|d| {
        d.metadata
            .name
            .as_ref()
            .map(|n| n.contains("simple-registry"))
            .unwrap_or(false)
    });

    let has_deployment = registry_deployment.is_some();
    print_test(7, "Registry deployment exists", has_deployment);

    if let Some(deploy) = registry_deployment {
        println!("  Deployment Name: {:?}", deploy.metadata.name);
        println!("  Replicas: {:?}", deploy.spec.as_ref().and_then(|s| s.replicas));
    }

    // Test 8: Verify service exists
    print_section("Test 8: Verify Registry Service");
    let services = km.services_list().await?;
    let registry_service = services.iter().find(|s| {
        s.metadata
            .name
            .as_ref()
            .map(|n| n.contains("simple-registry"))
            .unwrap_or(false)
    });

    let has_service = registry_service.is_some();
    print_test(8, "Registry service exists", has_service);

    if let Some(svc) = registry_service {
        println!("  Service Name: {:?}", svc.metadata.name);
        
        if let Some(spec) = svc.spec.as_ref() {
            if let Some(ports) = spec.ports.as_ref() {
                println!("  Ports:");
                for port in ports {
                    println!("    - Port: {:?}, Target: {:?}", port.port, port.target_port);
                }
            }
        }
    }

    // Test 9: Deploy with authentication
    print_section("Test 9: Deploy Registry with Authentication");
    println!("Deploying registry with basic authentication...");
    
    let auth_config = RegistryConfigBuilder::new("secure-registry")
        .with_auth("admin", "secretpassword")
        .node_port(30501)
        .timeout_secs(120)
        .reset(true)
        .build();
    
    let auth_result = km.deploy_registry("secure-registry", auth_config).await?;
    
    let has_auth = auth_result.username.is_some() && auth_result.password.is_some();
    print_test(9, "Registry with authentication deployment", has_auth);
    
    if let Some(username) = &auth_result.username {
        println!("  Username: {}", username);
    }
    if let Some(secret_name) = &auth_result.auth_secret_name {
        println!("  Auth Secret: {}", secret_name);
    }

    // Test 10: Verify secrets for authenticated registry
    print_section("Test 10: Verify Authentication Secret");
    let secrets = km.secrets_list().await?;
    let has_auth_secret = auth_result.auth_secret_name.as_ref().map_or(false, |secret_name| {
        secrets.iter().any(|s| {
            s.metadata
                .name
                .as_ref()
                .map(|n| n.contains(secret_name))
                .unwrap_or(false)
        })
    });
    
    print_test(10, "Authentication secret created", has_auth_secret);

    // Summary
    print_section("Summary");
    println!("✓ Registry Deployment Tests Complete\n");
    println!("Simple Registry:");
    println!("  Connection: {}", result.connection_string());
    if let Some(external) = result.external_connection_string() {
        println!("  External: {}", external);
    }
    println!("  Push images to: {}image:tag", result.image_prefix());

    println!("\nAuthenticated Registry:");
    println!("  Connection: {}", auth_result.connection_string());
    if let Some(external) = auth_result.external_connection_string() {
        println!("  External: {}", external);
    }
    println!("  Username: {:?}", auth_result.username);
    println!("  Push images to: {}image:tag", auth_result.image_prefix());

    // Cleanup
    print_section("Cleanup");
    println!("Cleaning up registry deployments...");
    
    km.delete_registry("simple-registry").await?;
    println!("✓ Deleted simple-registry");
    
    km.delete_registry("secure-registry").await?;
    println!("✓ Deleted secure-registry");
    
    km.namespace_delete("registry").await?;
    println!("✓ Deleted registry namespace");

    print_section("All Tests Complete!");
    println!("✓ Registry deployment and verification successful\n");

    Ok(())
}
