use lmrc_postgres::{PostgresConfig, parse_pg_hba_rules};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt()
.with_max_level(tracing::Level::INFO)
.init();
println!("=== PostgreSQL Configuration Backup & Rollback ===\n");
let _config = PostgresConfig::builder()
.version("15")
.database_name("myapp")
.username("appuser")
.password("secure_password")
.listen_addresses("0.0.0.0/0")
.port(5432)
.max_connections(100)
.shared_buffers("256MB")
.build()?;
println!("Example 1: Dry-Run Mode");
println!("------------------------");
println!("Dry-run allows you to preview changes before applying them.\n");
println!("Code:");
println!("```rust");
println!("// Preview what changes would be made");
println!("let diff = manager.dry_run_configure().await?;");
println!();
println!("if diff.has_changes() {{");
println!(" println!(\"Would make {{}} change(s):\", diff.len());");
println!(" println!(\"{{}}\", diff);");
println!(" ");
println!(" // If changes look good, apply them");
println!(" manager.apply_diff(&diff).await?;");
println!("}}");
println!("```\n");
println!("Example 2: Safe Configuration Apply");
println!("------------------------------------");
println!("apply_diff_safe() automatically creates a backup and rolls back on failure.\n");
println!("Code:");
println!("```rust");
println!("let diff = manager.diff().await?;");
println!();
println!("if diff.has_changes() {{");
println!(" // This method:");
println!(" // 1. Creates a backup");
println!(" // 2. Applies changes");
println!(" // 3. Rolls back automatically if anything fails");
println!(" manager.apply_diff_safe(&diff).await?;");
println!("}}");
println!("```\n");
println!("Example 3: Manual Backup & Restore");
println!("-----------------------------------");
println!("Code:");
println!("```rust");
println!("// Create a backup manually");
println!("let backup = manager.backup_config().await?;");
println!("println!(\"Backup created: {{}}\", backup.backup_dir);");
println!();
println!("// Make some changes...");
println!("manager.configure().await?;");
println!();
println!("// If something went wrong, restore from backup");
println!("manager.restore_backup(&backup).await?;");
println!("```\n");
println!("Example 4: Quick Rollback");
println!("--------------------------");
println!("Rollback to the most recent backup in one command.\n");
println!("Code:");
println!("```rust");
println!("// Oops, the last change broke something!");
println!("// Quickly roll back to the previous configuration");
println!("manager.rollback_config().await?;");
println!("println!(\"Rolled back to previous configuration\");");
println!("```\n");
println!("Example 5: Backup Management");
println!("-----------------------------");
println!("Code:");
println!("```rust");
println!("// List all available backups");
println!("let backups = manager.list_backups().await?;");
println!("for backup in &backups {{");
println!(" println!(\"Backup: {{}} - {{}} files\", ");
println!(" backup.timestamp, backup.files.len());");
println!("}}");
println!();
println!("// Keep only the 5 most recent backups");
println!("let deleted = manager.cleanup_old_backups(5).await?;");
println!("println!(\"Deleted {{}} old backup(s)\", deleted);");
println!("```\n");
println!("Example 6: pg_hba.conf Inspection");
println!("----------------------------------");
println!("Read and parse pg_hba.conf authentication rules.\n");
println!("Code:");
println!("```rust");
println!("// Read current pg_hba.conf");
println!("let pg_hba_content = manager.read_pg_hba().await?;");
println!();
println!("// Parse rules");
println!("let rules = parse_pg_hba_rules(&pg_hba_content);");
println!("for rule in rules {{");
println!(" println!(\"Rule: {{}} - {{}} - {{}}\",");
println!(" rule.rule_type, rule.database, rule.method);");
println!("}}");
println!("```\n");
println!("Example 7: Complete Workflow");
println!("------------------------------");
println!("A typical safe configuration change workflow:\n");
println!("1. Check what would change (dry-run)");
println!("2. Create explicit backup");
println!("3. Apply changes");
println!("4. Verify");
println!("5. If issues, rollback\n");
println!("Code:");
println!("```rust");
println!("// Step 1: Preview changes");
println!("let diff = manager.dry_run_configure().await?;");
println!("if !diff.has_changes() {{");
println!(" println!(\"No changes needed\");");
println!(" return Ok(());");
println!("}}");
println!();
println!("// Step 2: Show changes to user");
println!("println!(\"The following changes will be made:\");");
println!("println!(\"{{}}\", diff);");
println!();
println!("// Step 3: Create backup before changes");
println!("let backup = manager.backup_config().await?;");
println!("println!(\"Created backup: {{}}\", backup.timestamp);");
println!();
println!("// Step 4: Apply changes");
println!("match manager.apply_diff(&diff).await {{");
println!(" Ok(_) => println!(\"✓ Changes applied successfully\"),");
println!(" Err(e) => {{");
println!(" eprintln!(\"✗ Error applying changes: {{}}\", e);");
println!(" println!(\"Rolling back to backup...\");");
println!(" manager.restore_backup(&backup).await?;");
println!(" return Err(e.into());");
println!(" }}");
println!("}}");
println!();
println!("// Step 5: Verify changes");
println!("manager.test_connection().await?;");
println!("println!(\"✓ Configuration verified\");");
println!("```\n");
println!("Example 8: pg_hba.conf Diff Detection");
println!("--------------------------------------");
println!("Compare pg_hba.conf rules to detect changes.\n");
let example_current = r#"
# PostgreSQL Client Authentication Configuration File
# TYPE DATABASE USER ADDRESS METHOD
local all postgres peer
host all all 127.0.0.1/32 md5
"#;
let example_desired = r#"
# PostgreSQL Client Authentication Configuration File
# TYPE DATABASE USER ADDRESS METHOD
local all postgres trust
host all all 127.0.0.1/32 md5
host all all 0.0.0.0/0 md5
"#;
println!("Current pg_hba.conf:");
println!("{}", example_current);
println!("Desired pg_hba.conf:");
println!("{}", example_desired);
let current_rules = parse_pg_hba_rules(example_current);
let desired_rules = parse_pg_hba_rules(example_desired);
println!("Parsed current rules: {}", current_rules.len());
for (i, rule) in current_rules.iter().enumerate() {
println!(" {}: {}", i + 1, rule);
}
println!("\nParsed desired rules: {}", desired_rules.len());
for (i, rule) in desired_rules.iter().enumerate() {
println!(" {}: {}", i + 1, rule);
}
use lmrc_postgres::diff_pg_hba_rules;
let diffs = diff_pg_hba_rules(¤t_rules, &desired_rules);
if !diffs.is_empty() {
println!(
"\npg_hba.conf changes detected ({} difference(s)):",
diffs.len()
);
for diff in diffs {
println!(" {}", diff);
}
} else {
println!("\nNo pg_hba.conf changes detected");
}
println!("\n=== Key Features Summary ===\n");
println!("✓ Dry-run mode - Preview changes without applying");
println!("✓ Automatic backups - Create backups before changes");
println!("✓ Safe apply - Automatic rollback on failure");
println!("✓ Manual rollback - Restore to any previous backup");
println!("✓ Backup management - List and cleanup old backups");
println!("✓ pg_hba.conf support - Read, parse, and diff authentication rules");
println!("\n=== Complete ===");
Ok(())
}