use server::config::Config;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("=== ROOT_PATH Configuration Example ===\n");

    // Example 1: Using default root path (current directory)
    println!("1. Default ROOT_PATH behavior:");
    let config = Config::load()?;
    println!("   Root path: {}", config.root_path);
    println!("   Assets dir: {}", config.static_files.assets_dir);
    println!("   Site root: {}", config.static_files.site_root);
    println!("   Logs dir: {}", config.server_dirs.logs_dir);
    println!();

    // Example 2: Demonstrating path resolution with custom root
    println!("2. Path resolution with custom root:");
    println!("   Note: ROOT_PATH can be set via environment variable");
    println!("   Example: ROOT_PATH=/var/www/myapp ./my-app");
    println!("   Current ROOT_PATH: {}", config.root_path);
    println!();

    // Example 3: Using get_absolute_path method
    println!("3. Converting relative paths to absolute:");
    let relative_path = "uploads/images";
    match config.get_absolute_path(relative_path) {
        Ok(absolute_path) => {
            println!("   Relative: {}", relative_path);
            println!("   Absolute: {}", absolute_path);
        }
        Err(e) => {
            println!("   Error resolving path: {}", e);
        }
    }
    println!();

    // Example 4: Demonstrating path resolution behavior
    println!("4. Path resolution examples:");

    let test_cases = vec![
        ("relative/path", "Relative path"),
        ("./config", "Current directory relative"),
        ("../parent", "Parent directory relative"),
        ("/absolute/path", "Absolute path (unchanged)"),
    ];

    let config = Config::load()?;
    for (path, description) in test_cases {
        match config.get_absolute_path(path) {
            Ok(resolved) => {
                println!("   {} ({}): {}", description, path, resolved);
            }
            Err(e) => {
                println!("   {} ({}): Error - {}", description, path, e);
            }
        }
    }
    println!();

    // Example 5: Configuration file paths
    println!("5. Configuration file discovery:");
    println!("   The system looks for config files in this order:");
    println!("   1. Path specified by CONFIG_FILE environment variable");
    println!("   2. Environment-specific files (config.dev.toml, config.prod.toml)");
    println!("   3. Default config.toml");
    println!("   4. Searches from current directory up to root directory");
    println!();

    // Example 6: Directory structure with ROOT_PATH
    println!("6. Recommended directory structure:");
    println!("   ROOT_PATH/");
    println!("   ├── config.toml");
    println!("   ├── config.dev.toml");
    println!("   ├── config.prod.toml");
    println!("   ├── public/          (static assets)");
    println!("   ├── content/         (content files)");
    println!("   ├── uploads/         (user uploads)");
    println!("   ├── logs/            (application logs)");
    println!("   ├── cache/           (temporary cache)");
    println!("   ├── data/            (application data)");
    println!("   └── backups/         (backup files)");
    println!();

    // Example 7: Environment variable usage
    println!("7. Useful environment variables:");
    println!("   ROOT_PATH=/path/to/app        # Set application root");
    println!("   CONFIG_FILE=/path/config.toml # Override config file");
    println!("   ENVIRONMENT=production        # Set environment");
    println!("   SERVER_HOST=0.0.0.0          # Override server host");
    println!("   SERVER_PORT=8080              # Override server port");
    println!("   DATABASE_URL=postgresql://... # Override database URL");
    println!();

    // Example 8: Docker deployment example
    println!("8. Docker deployment example:");
    println!("   FROM rust:latest");
    println!("   WORKDIR /app");
    println!("   COPY . .");
    println!("   ENV ROOT_PATH=/app");
    println!("   ENV ENVIRONMENT=production");
    println!("   RUN cargo build --release");
    println!("   EXPOSE 3030");
    println!("   CMD [\"./target/release/server\"]");
    println!();

    println!("✅ ROOT_PATH configuration example completed!");
    println!("💡 Tips:");
    println!("   - Use absolute paths in production for clarity");
    println!("   - Set ROOT_PATH in your deployment environment");
    println!("   - All relative paths in config files are resolved against ROOT_PATH");
    println!("   - Directory creation is automatic if paths don't exist");

    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::fs;
    use tempfile::tempdir;

    #[test]
    fn test_root_path_resolution() {
        // Create a temporary directory structure
        let temp_dir = tempdir().unwrap();
        let temp_path = temp_dir.path().to_string_lossy().to_string();

        // Note: In real tests, you would set environment variables before process start
        // For this test, we'll create a config with a custom root path in the TOML

        // Create test directories
        let public_dir = temp_dir.path().join("public");
        let logs_dir = temp_dir.path().join("logs");
        fs::create_dir_all(&public_dir).unwrap();
        fs::create_dir_all(&logs_dir).unwrap();

        // Create a test config file with custom root path
        let config_content = format!(
            r#"
root_path = "{}"

[server]
protocol = "http"
host = "localhost"
port = 3030
environment = "development"
log_level = "info"

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

[session]
secret = "test-secret"
cookie_name = "session_id"
cookie_secure = false
cookie_http_only = true
cookie_same_site = "lax"
max_age = 3600

[cors]
allowed_origins = ["http://localhost:3030"]
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 = true
csrf_token_name = "csrf_token"
rate_limit_requests = 100
rate_limit_window = 60
bcrypt_cost = 12

[oauth]
enabled = false

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

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

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

[logging]
format = "json"
level = "info"
file_path = "logs/app.log"
max_file_size = 10485760
max_files = 5
enable_console = true
enable_file = false

[features]
auth = true
tls = false
content_db = true
two_factor_auth = false
"#,
            temp_path.replace("\\", "\\\\")
        );

        let config_path = temp_dir.path().join("config.toml");
        fs::write(&config_path, config_content).unwrap();

        // Test path resolution
        let config = Config::load_from_file(&config_path).unwrap();

        // The public_dir should be resolved to an absolute path
        assert!(config.static_files.assets_dir.starts_with(&temp_path));
        assert!(config.server_dirs.logs_dir.starts_with(&temp_path));

        // Test get_absolute_path method
        let relative_path = "test/path";
        let absolute_path = config.get_absolute_path(relative_path).unwrap();
        assert!(absolute_path.contains(&temp_path));
        assert!(absolute_path.contains("test/path"));
    }
}
