# Server Foundation Usage Patterns

## Overview
The server foundation provides multiple usage patterns to fit different application needs, from simple direct imports to complex modular composition.

## Pattern 1: Direct Import (Simplest)

**Best for**: Quick prototypes, simple applications, getting started

```rust
use server::run_server;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // One line to get a complete server running
    run_server().await?;
    Ok(())
}
```

**What you get automatically:**
- HTTP server bound to 0.0.0.0:3030
- Route configuration loaded from content/routes/
- Static file serving from public/
- CORS and security headers
- Health check endpoints
- Structured logging setup
- Environment variable configuration

**Configuration through environment:**
```bash
HOST=127.0.0.1 PORT=8080 RUST_LOG=debug cargo run
```

## Pattern 2: Configuration-Based

**Best for**: Applications needing specific settings but standard structure

```rust
use server::{run_server_with_config, ServerConfig, DatabaseConfig, AuthConfig};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = ServerConfig::builder()
        .host("0.0.0.0")
        .port(8080)
        .log_level("debug")
        .enable_features(["auth", "content-db", "email"])
        .database(DatabaseConfig {
            url: "postgresql://localhost/myapp".to_string(),
            max_connections: Some(20),
            timeout_seconds: Some(30),
        })
        .auth(AuthConfig {
            jwt_secret: "your-super-secret-key-here".to_string(),
            session_timeout_hours: Some(24),
            enable_oauth: true,
            enable_2fa: false,
        })
        .content_path("my-content")
        .build();

    run_server_with_config(config).await?;
    Ok(())
}
```

**Advanced configuration:**
```rust
use server::{
    ServerConfig, SecurityConfig, PerformanceConfig, 
    EmailConfig, MetricsConfig
};

let config = ServerConfig::builder()
    .security_config(SecurityConfig {
        enable_https: true,
        cert_path: Some("/path/to/cert.pem".to_string()),
        key_path: Some("/path/to/key.pem".to_string()),
        cors_origins: vec!["https://mydomain.com".to_string()],
        enable_rate_limiting: true,
        rate_limit_requests: 100,
        rate_limit_window_seconds: 60,
    })
    .performance_config(PerformanceConfig {
        worker_threads: Some(4),
        enable_compression: true,
        static_cache_max_age: 86400, // 1 day
        enable_http2: true,
    })
    .email_config(EmailConfig {
        provider: EmailProvider::SMTP,
        smtp_host: "smtp.gmail.com".to_string(),
        smtp_port: 587,
        from_address: "noreply@myapp.com".to_string(),
        // credentials loaded from environment
    })
    .metrics_config(MetricsConfig {
        enabled: true,
        path: "/metrics".to_string(),
        include_route_metrics: true,
        include_system_metrics: true,
    })
    .build();

run_server_with_config(config).await?;
```

## Pattern 3: Extended/Additive

**Best for**: Adding custom functionality to the foundation server

```rust
use server::{create_base_app, serve_custom_app, ServerConfig, setup_tracing};
use axum::{Router, routing::{get, post}, middleware, response::Json};
use serde_json::{json, Value};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = ServerConfig::builder()
        .enable_features(["auth", "metrics"])
        .build();

    setup_tracing(&config)?;

    // Start with foundation base app (includes all standard routes)
    let base_app = create_base_app(&config).await?;

    // Add custom routes and middleware
    let app = base_app
        // Custom API routes
        .route("/api/custom/health", get(custom_health))
        .route("/api/custom/data", get(get_custom_data))
        .route("/api/custom/upload", post(handle_upload))
        
        // Custom middleware stack
        .layer(middleware::from_fn(request_logging_middleware))
        .layer(middleware::from_fn(custom_auth_middleware))
        
        // Custom error handling
        .layer(middleware::from_fn(error_handler_middleware));

    serve_custom_app(app, config).await?;
    Ok(())
}

// Custom route handlers
async fn custom_health() -> Json<Value> {
    Json(json!({
        "status": "healthy",
        "custom_service": "running",
        "timestamp": chrono::Utc::now().to_rfc3339()
    }))
}

async fn get_custom_data() -> Json<Value> {
    // Your custom business logic
    let data = load_custom_data().await;
    Json(json!({ "data": data }))
}

async fn handle_upload(
    // Custom upload handling logic
    body: axum::body::Bytes
) -> Result<Json<Value>, CustomError> {
    // Process upload
    let result = process_upload(body).await?;
    Ok(Json(json!({ "upload_id": result.id })))
}

// Custom middleware
async fn request_logging_middleware<B>(
    request: axum::http::Request<B>,
    next: axum::middleware::Next<B>,
) -> axum::response::Response {
    let method = request.method().clone();
    let uri = request.uri().clone();
    let start = std::time::Instant::now();
    
    let response = next.run(request).await;
    
    let duration = start.elapsed();
    tracing::info!("Custom: {} {} - {}ms", method, uri, duration.as_millis());
    
    response
}
```

## Pattern 4: Override/Replace

**Best for**: Custom server logic while using foundation utilities

```rust
use server::{ServerConfig, setup_tracing, middleware, utils};
use axum::{Router, routing::get, serve};
use tokio::net::TcpListener;
use tower::ServiceBuilder;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = ServerConfig::from_env()?;
    setup_tracing(&config)?;

    // Build completely custom app using foundation utilities
    let app = build_custom_app(&config).await?;
    
    // Custom server startup with advanced configuration
    start_custom_server(app, &config).await?;
    
    Ok(())
}

async fn build_custom_app(config: &ServerConfig) -> Result<Router, ServerError> {
    // Build your own app structure using foundation utilities
    let middleware_stack = ServiceBuilder::new()
        .layer(middleware::cors_middleware(config))
        .layer(middleware::security_headers_middleware())
        .layer(custom_metrics_middleware())
        .layer(custom_caching_middleware());

    let app = Router::new()
        // Custom route structure
        .route("/", get(custom_home))
        .route("/api/v1/*path", get(api_v1_handler))
        .route("/api/v2/*path", get(api_v2_handler))
        .route("/admin/*path", get(admin_handler))
        
        // Use foundation utilities for specific needs
        .merge(utils::health_routes())
        .merge(utils::static_file_routes(config))
        
        // Custom middleware stack
        .layer(middleware_stack);

    Ok(app)
}

async fn start_custom_server(app: Router, config: &ServerConfig) -> Result<(), ServerError> {
    let addr = format!("{}:{}", config.host, config.port);
    
    // Advanced listener configuration
    let listener = TcpListener::bind(&addr).await?;
    
    // Custom server options
    let server = serve(listener, app)
        .with_graceful_shutdown(shutdown_signal());
    
    tracing::info!("🚀 Custom server with foundation utilities running on {}", addr);
    server.await?;
    
    Ok(())
}

async fn shutdown_signal() {
    tokio::signal::ctrl_c()
        .await
        .expect("failed to install CTRL+C signal handler");
    tracing::info!("Shutdown signal received");
}
```

## Pattern 5: Modular Composition

**Best for**: Complex applications with fine-grained control

```rust
use server::{
    ServerConfig, setup_tracing,
    middleware::{cors_middleware, security_headers_middleware, auth_middleware},
    routing::{create_api_routes, create_admin_routes, create_static_routes},
    database::{create_pool, run_migrations},
    auth::{setup_auth_service, JwtAuthService},
    email::{setup_email_service, SMTPEmailService},
    metrics::{setup_metrics, PrometheusMetrics},
};
use axum::Router;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = ServerConfig::from_env()?;
    
    // Step 1: Setup core services
    let services = setup_services(&config).await?;
    
    // Step 2: Build app with modular composition
    let app = compose_application(&config, services).await?;
    
    // Step 3: Start server with custom configuration
    start_composed_server(app, &config).await?;
    
    Ok(())
}

// Service container for dependency injection
#[derive(Clone)]
struct Services {
    database: Option<sqlx::PgPool>,
    auth: Option<Arc<JwtAuthService>>,
    email: Option<Arc<SMTPEmailService>>,
    metrics: Option<Arc<PrometheusMetrics>>,
}

async fn setup_services(config: &ServerConfig) -> Result<Services, ServerError> {
    setup_tracing(config)?;
    
    // Database setup (if feature enabled)
    let database = if config.has_feature("auth") || config.has_feature("content-db") {
        let pool = create_pool(config.database.as_ref().unwrap()).await?;
        run_migrations(&pool).await?;
        Some(pool)
    } else {
        None
    };
    
    // Auth service setup (if feature enabled)
    let auth = if config.has_feature("auth") {
        Some(Arc::new(setup_auth_service(config.auth.as_ref().unwrap())?))
    } else {
        None
    };
    
    // Email service setup (if feature enabled)
    let email = if config.has_feature("email") {
        Some(Arc::new(setup_email_service(config.email.as_ref().unwrap()).await?))
    } else {
        None
    };
    
    // Metrics setup (if feature enabled)
    let metrics = if config.has_feature("metrics") {
        Some(Arc::new(setup_metrics(config.metrics.as_ref().unwrap())?))
    } else {
        None
    };
    
    Ok(Services { database, auth, email, metrics })
}

async fn compose_application(
    config: &ServerConfig,
    services: Services,
) -> Result<Router, ServerError> {
    let mut app = Router::new();
    
    // Core routes (always included)
    app = app.merge(create_static_routes(config));
    
    // API routes (if database available)
    if let Some(ref db) = services.database {
        app = app.merge(create_api_routes(config, db.clone()).await?);
    }
    
    // Admin routes (if auth enabled)
    if let Some(ref auth) = services.auth {
        app = app.merge(create_admin_routes(config, auth.clone()).await?);
    }
    
    // Custom feature routes
    app = app.merge(create_custom_routes(&services).await?);
    
    // Middleware stack (order matters - outer to inner)
    if let Some(ref metrics) = services.metrics {
        app = app.layer(metrics_middleware(metrics.clone()));
    }
    
    app = app.layer(cors_middleware(config));
    app = app.layer(security_headers_middleware());
    
    if let Some(ref auth) = services.auth {
        app = app.layer(auth_middleware(auth.clone()));
    }
    
    // State injection for handlers
    if let Some(db) = services.database {
        app = app.with_state(db);
    }
    
    Ok(app)
}

async fn create_custom_routes(services: &Services) -> Result<Router, ServerError> {
    let mut routes = Router::new();
    
    // Email routes (if email service available)
    if let Some(ref email_service) = services.email {
        routes = routes.merge(create_email_routes(email_service.clone()));
    }
    
    // Analytics routes (if metrics available)
    if let Some(ref metrics) = services.metrics {
        routes = routes.merge(create_analytics_routes(metrics.clone()));
    }
    
    Ok(routes)
}
```

## Development vs Production Patterns

### Development Configuration
```rust
use server::{ServerConfig, DevelopmentConfig};

let config = if cfg!(debug_assertions) {
    ServerConfig::builder()
        .enable_dev_features(true)
        .development_config(DevelopmentConfig {
            hot_reload: true,
            detailed_errors: true,
            cors_permissive: true,
            log_requests: true,
            enable_playground: true,
        })
        .build()
} else {
    ServerConfig::from_env()?
};
```

### Production Configuration
```rust
use server::{ServerConfig, ProductionConfig, SecurityConfig};

let config = ServerConfig::builder()
    .production_config(ProductionConfig {
        worker_threads: num_cpus::get(),
        enable_clustering: true,
        graceful_shutdown_timeout: 30,
        health_check_interval: 30,
    })
    .security_config(SecurityConfig {
        enable_https: true,
        hsts_max_age: 31536000, // 1 year
        enable_csrf_protection: true,
        content_security_policy: Some("default-src 'self'".to_string()),
        rate_limiting: true,
    })
    .enable_features(["auth", "content-db", "email", "tls", "metrics"])
    .build();
```

## Testing Patterns

### Unit Testing Foundation Functions
```rust
#[cfg(test)]
mod tests {
    use super::*;
    use server::test_utils::{TestServer, TestConfig};
    
    #[tokio::test]
    async fn test_foundation_server_startup() {
        let config = TestConfig::default();
        let server = TestServer::new(config);
        
        let response = server.get("/health").await;
        assert_eq!(response.status(), 200);
    }
    
    #[tokio::test]
    async fn test_custom_routes() {
        let config = ServerConfig::builder()
            .enable_test_mode(true)
            .build();
            
        let app = create_base_app(&config).await.unwrap();
        let server = TestServer::from_app(app);
        
        let response = server.get("/api/custom").await;
        assert_eq!(response.status(), 200);
    }
}
```

### Integration Testing
```rust
#[cfg(test)]
mod integration_tests {
    use super::*;
    
    #[tokio::test]
    async fn test_full_application() {
        // Start real server in test mode
        let config = ServerConfig::test_config();
        let server_handle = tokio::spawn(run_server_with_config(config));
        
        // Test API endpoints
        let client = reqwest::Client::new();
        let response = client
            .get("http://127.0.0.1:3030/health")
            .send()
            .await
            .unwrap();
            
        assert_eq!(response.status(), 200);
        
        // Cleanup
        server_handle.abort();
    }
}
```

## Performance Optimization Patterns

### Connection Pooling
```rust
use server::{ServerConfig, DatabaseConfig, ConnectionPoolConfig};

let config = ServerConfig::builder()
    .database(DatabaseConfig {
        url: "postgresql://localhost/myapp".to_string(),
        pool_config: ConnectionPoolConfig {
            max_connections: 20,
            min_connections: 5,
            acquire_timeout: Duration::from_secs(10),
            idle_timeout: Some(Duration::from_secs(600)),
            max_lifetime: Some(Duration::from_secs(1800)),
        },
    })
    .build();
```

### Caching Middleware
```rust
use server::{create_base_app, middleware::caching_middleware};

let app = create_base_app(&config).await?
    .layer(caching_middleware(CachingConfig {
        static_files_max_age: Duration::from_secs(86400), // 1 day
        api_cache_max_age: Duration::from_secs(300),       // 5 minutes
        enable_etags: true,
        enable_gzip: true,
    }));
```

## Error Handling Patterns

### Custom Error Types
```rust
use server::{ServerError, create_base_app};

#[derive(Debug, thiserror::Error)]
enum CustomError {
    #[error("Database error: {0}")]
    Database(#[from] sqlx::Error),
    
    #[error("Authentication failed: {0}")]
    Auth(String),
    
    #[error("Business logic error: {0}")]
    Business(String),
}

impl axum::response::IntoResponse for CustomError {
    fn into_response(self) -> axum::response::Response {
        match self {
            CustomError::Database(_) => {
                (StatusCode::INTERNAL_SERVER_ERROR, "Database error").into_response()
            }
            CustomError::Auth(msg) => {
                (StatusCode::UNAUTHORIZED, msg).into_response()
            }
            CustomError::Business(msg) => {
                (StatusCode::BAD_REQUEST, msg).into_response()
            }
        }
    }
}
```

## Choosing the Right Pattern

| Need | Pattern | Complexity | Flexibility | Use Case |
|------|---------|------------|-------------|----------|
| Quick start | Direct Import | Low | Low | Prototypes, demos |
| Custom settings | Configuration | Low | Medium | Standard apps with specific needs |
| Add features | Extended | Medium | Medium | Apps needing custom endpoints |
| Custom logic | Override | High | High | Unique server requirements |
| Fine control | Modular | High | Maximum | Complex enterprise applications |

## Migration Between Patterns

Start simple and migrate to more complex patterns as needs grow:

1. **Start with Direct Import** for initial development
2. **Move to Configuration** when you need custom settings
3. **Use Extended pattern** when you need to add custom routes
4. **Consider Override or Modular** for complex applications

Each pattern builds on foundation components, so migration is incremental and maintains compatibility with existing code.
