//! Configuration System Example
//!
//! This example demonstrates how to use the configuration system
//! with TOML files and environment variable overrides.

use server::config::{Config, Environment, Protocol};
use tempfile::tempdir;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("=== Configuration System Example ===\n");

    // Example 1: Load default configuration
    println!("1. Loading default configuration...");
    match Config::load() {
        Ok(config) => {
            println!("✓ Configuration loaded successfully");
            println!("  Server: {}:{}", config.server.host, config.server.port);
            println!("  Environment: {:?}", config.server.environment);
            println!("  Database: {}", config.database.url);
            println!("  App Name: {}", config.app.name);
            println!("  Debug Mode: {}", config.app.debug);

            // Show server directories
            println!("  Server Directories:");
            println!("    Public: {}", config.server_dirs.public_dir);
            println!("    Uploads: {}", config.server_dirs.uploads_dir);
            println!("    Logs: {}", config.server_dirs.logs_dir);
            println!("    Cache: {}", config.server_dirs.cache_dir);
        }
        Err(e) => {
            println!("✗ Failed to load configuration: {}", e);
            println!("  This is expected if no config file exists");
        }
    }

    println!("\n{}\n", "=".repeat(50));

    // Example 2: Demonstrate TOML file loading
    println!("2. Testing TOML file loading...");

    let temp_dir = tempdir()?;
    let config_path = temp_dir.path().join("test_config.toml");

    let test_config = r#"
[server]
protocol = "http"
host = "localhost"
port = 4000
environment = "development"
log_level = "debug"

[database]
url = "postgresql://test:test@localhost:5432/test_db"
max_connections = 5
min_connections = 1
connect_timeout = 30
idle_timeout = 600
max_lifetime = 1800

[session]
secret = "test-secret-key"
cookie_name = "test_session"
cookie_secure = false
cookie_http_only = true
cookie_same_site = "lax"
max_age = 7200

[cors]
allowed_origins = ["http://localhost:4000"]
allowed_methods = ["GET", "POST"]
allowed_headers = ["Content-Type"]
allow_credentials = true
max_age = 3600

[static]
assets_dir = "public"
site_root = "target/site"
site_pkg_dir = "pkg"

[server_dirs]
public_dir = "public"
uploads_dir = "uploads"
logs_dir = "logs"
temp_dir = "tmp"
cache_dir = "cache"
config_dir = "config"
data_dir = "data"
backup_dir = "backups"

[security]
enable_csrf = false
csrf_token_name = "csrf_token"
rate_limit_requests = 1000
rate_limit_window = 60
bcrypt_cost = 4

[oauth]
enabled = false

[email]
enabled = false
smtp_host = "localhost"
smtp_port = 587
smtp_username = ""
smtp_password = ""
from_email = "test@example.com"
from_name = "Test App"

[redis]
enabled = false
url = "redis://localhost:6379"
pool_size = 10
connection_timeout = 5
command_timeout = 5

[app]
name = "Test Application"
version = "0.1.0"
debug = true
enable_metrics = true
enable_health_check = true
enable_compression = false
max_request_size = 10485760

[logging]
format = "text"
level = "debug"
file_path = "logs/test.log"
max_file_size = 10485760
max_files = 5
enable_console = true
enable_file = true

[content]
enabled = false
content_dir = "content"
cache_enabled = false
cache_ttl = 60
max_file_size = 5242880

[features]
auth = true
tls = false
content_db = true
two_factor_auth = false
"#;

    std::fs::write(&config_path, test_config)?;

    match Config::load_from_file(&config_path) {
        Ok(config) => {
            println!("✓ Configuration loaded from TOML file");
            println!("  Server: {}:{}", config.server.host, config.server.port);
            println!("  App Name: {}", config.app.name);
            println!("  Database: {}", config.database.url);
        }
        Err(e) => {
            println!("✗ Failed to load from TOML file: {}", e);
        }
    }

    println!("\n{}\n", "=".repeat(50));

    // Example 3: Demonstrate configuration validation
    println!("3. Testing configuration validation...");

    // Create a config that should pass validation
    let valid_config = Config::default();
    match valid_config.validate() {
        Ok(_) => {
            println!("✓ Default configuration validation passed");
        }
        Err(e) => {
            println!("✗ Default configuration validation failed: {}", e);
        }
    }

    println!("\n{}\n", "=".repeat(50));

    // Example 4: Demonstrate configuration helper methods
    println!("4. Testing configuration helper methods...");

    let config = Config::default();
    println!("✓ Configuration methods:");
    println!("  Server Address: {}", config.server_address());
    println!("  Server URL: {}", config.server_url());
    println!("  Is Development: {}", config.is_development());
    println!("  Is Production: {}", config.is_production());
    println!("  Requires TLS: {}", config.requires_tls());

    // Database pool configuration
    let pool_config = config.database_pool_config();
    println!("  Database Pool Config:");
    println!("    Max Connections: {}", pool_config.max_connections);
    println!("    Min Connections: {}", pool_config.min_connections);
    println!("    Connect Timeout: {:?}", pool_config.connect_timeout);

    println!("\n{}\n", "=".repeat(50));

    // Example 5: Show feature flags
    println!("5. Feature flags configuration...");

    let config = Config::default();
    println!("✓ Feature flags:");
    println!("  Auth: {:?}", config.features.auth);
    println!("  RBAC: {:?}", config.features.rbac);
    println!("  Content: {:?}", config.features.content);
    println!("  Security: {:?}", config.features.security);

    println!("\n{}\n", "=".repeat(50));

    // Example 6: Show server directories configuration
    println!("6. Server directories configuration...");

    let config = Config::default();
    println!("✓ Server directories:");
    println!("  Public Directory: {}", config.server_dirs.public_dir);
    println!("  Uploads Directory: {}", config.server_dirs.uploads_dir);
    println!("  Logs Directory: {}", config.server_dirs.logs_dir);
    println!("  Temp Directory: {}", config.server_dirs.temp_dir);
    println!("  Cache Directory: {}", config.server_dirs.cache_dir);
    println!("  Config Directory: {}", config.server_dirs.config_dir);
    println!("  Data Directory: {}", config.server_dirs.data_dir);
    println!("  Backup Directory: {}", config.server_dirs.backup_dir);

    println!("\n{}\n", "=".repeat(50));

    // Example 7: Show security configuration
    println!("7. Security configuration...");

    let config = Config::default();
    println!("✓ Security settings:");
    println!("  CSRF Enabled: {}", config.security.enable_csrf);
    println!(
        "  Rate Limit: {} requests/{} seconds",
        config.security.rate_limit_requests, config.security.rate_limit_window
    );
    println!("  BCrypt Cost: {}", config.security.bcrypt_cost);
    println!("  Session Config:");
    println!("    Cookie Name: {}", config.session.cookie_name);
    println!("    Cookie Secure: {}", config.session.cookie_secure);
    println!("    Cookie HTTP Only: {}", config.session.cookie_http_only);
    println!("    Max Age: {} seconds", config.session.max_age);

    println!("\n{}\n", "=".repeat(50));

    // Example 8: Create a custom configuration programmatically
    println!("8. Creating custom configuration...");

    let custom_config = Config {
        server: server::config::ServerConfig {
            protocol: Protocol::Http,
            host: "0.0.0.0".to_string(),
            port: 8080,
            environment: Environment::Development,
            log_level: "debug".to_string(),
            tls: None,
        },
        app: server::config::AppConfig {
            name: "Custom Example App".to_string(),
            version: "2.0.0".to_string(),
            debug: true,
            enable_metrics: true,
            enable_health_check: true,
            enable_compression: false,
            max_request_size: 5 * 1024 * 1024, // 5MB
            admin_email: Some("admin@example.com".to_string()),
        },
        server_dirs: server::config::ServerDirConfig {
            public_dir: "custom_public".to_string(),
            uploads_dir: "custom_uploads".to_string(),
            logs_dir: "custom_logs".to_string(),
            temp_dir: "custom_tmp".to_string(),
            cache_dir: "custom_cache".to_string(),
            config_dir: "custom_config".to_string(),
            data_dir: "custom_data".to_string(),
            backup_dir: "custom_backups".to_string(),
            template_dir: Some("custom_templates".to_string()),
        },
        ..Default::default()
    };

    println!("✓ Custom configuration created:");
    println!("  App Name: {}", custom_config.app.name);
    println!("  Server: {}", custom_config.server_address());
    println!("  Metrics Enabled: {}", custom_config.app.enable_metrics);
    println!(
        "  Custom Public Dir: {}",
        custom_config.server_dirs.public_dir
    );
    println!(
        "  Custom Uploads Dir: {}",
        custom_config.server_dirs.uploads_dir
    );

    println!("\n{}\n", "=".repeat(50));
    println!("Configuration example completed successfully!");
    println!("\nTo use this configuration system in your application:");
    println!("1. Create a config.toml file in your project root");
    println!("2. Use environment-specific files (config.dev.toml, config.prod.toml)");
    println!("3. Set environment variables to override specific settings");
    println!("4. Call Config::load() in your application");
    println!("5. Use config.server_dirs for all directory paths");

    Ok(())
}
