//! Configuration diff detection example
//!
//! This example demonstrates how to detect and apply configuration changes.

use lmrc_postgres::{PostgresConfig, PostgresManager};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    tracing_subscriber::fmt::init();

    // Initial configuration
    let config = PostgresConfig::builder()
        .version("15")
        .database_name("myapp")
        .username("myuser")
        .password("mypassword")
        .max_connections(100)
        .shared_buffers("256MB")
        .build()?;

    let manager = PostgresManager::builder()
        .config(config)
        .server_ip("192.168.1.100")
        .ssh_user("root")
        .ssh_password("ssh_password")
        .build()?;

    // Ensure PostgreSQL is installed
    println!("Setting up PostgreSQL...");
    manager.setup().await?;

    println!("\nChecking current configuration...");
    let diff = manager.diff().await?;

    if diff.has_changes() {
        println!("Configuration changes detected:");
        println!("{}", diff);
        println!("\nSummary: {}", diff.summary());

        println!("\nApplying changes...");
        manager.apply_diff(&diff).await?;
        println!("✓ Changes applied successfully!");
    } else {
        println!("No configuration changes detected");
    }

    // Now let's create a new configuration with changes
    println!("\n--- Updating configuration ---\n");

    let new_config = PostgresConfig::builder()
        .version("15")
        .database_name("myapp")
        .username("myuser")
        .password("mypassword")
        .max_connections(200) // Changed from 100
        .shared_buffers("512MB") // Changed from 256MB
        .build()?;

    let new_manager = PostgresManager::builder()
        .config(new_config)
        .server_ip("192.168.1.100")
        .ssh_user("root")
        .ssh_password("ssh_password")
        .build()?;

    println!("Detecting configuration changes...");
    let diff = new_manager.diff().await?;

    if diff.has_changes() {
        println!("\nConfiguration changes:");
        println!("{}", diff);

        // Show details
        println!("\nAdditions: {}", diff.additions().len());
        for change in diff.additions() {
            println!("  + {}", change);
        }

        println!("\nModifications: {}", diff.modifications().len());
        for change in diff.modifications() {
            println!("  ~ {}", change);
        }

        println!("\nRemovals: {}", diff.removals().len());
        for change in diff.removals() {
            println!("  - {}", change);
        }

        println!("\nApplying new configuration...");
        new_manager.apply_diff(&diff).await?;
        println!("✓ Configuration updated!");
    }

    Ok(())
}
