# Configuration System

This project uses a comprehensive TOML-based configuration system with environment variable overrides. The configuration system supports multiple environments, feature flags, and secure credential management.

## Quick Start

1. Copy one of the example configuration files to `config.toml`:
   ```bash
   cp config.dev.toml config.toml
   ```

2. Set environment-specific variables:
   ```bash
   export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
   export SESSION_SECRET="your-secret-key-here"
   ```

3. Run your application:
   ```bash
   cargo run
   ```

## Configuration Files

### File Priority

The configuration system looks for files in this order:

1. `$CONFIG_FILE` (if environment variable is set)
2. `config.{environment}.toml` (e.g., `config.dev.toml`, `config.prod.toml`)
3. `config.toml` (default fallback)

### Environment Detection

The environment is determined by the `ENVIRONMENT` variable:
- `development` or `dev` → looks for `config.dev.toml`
- `production` or `prod` → looks for `config.prod.toml`
- Default → looks for `config.toml`

## Configuration Structure

### Server Configuration

```toml
[server]
protocol = "http"          # "http" or "https"
host = "127.0.0.1"         # Server bind address
port = 3030                # Server port
environment = "development" # "development" or "production"
log_level = "info"         # "trace", "debug", "info", "warn", "error"

# TLS Configuration (required when protocol = "https")
[server.tls]
cert_path = "certs/server.crt"
key_path = "certs/server.key"
```

### Database Configuration

```toml
[database]
url = "postgresql://user:pass@localhost:5432/dbname"
max_connections = 10
min_connections = 1
connect_timeout = 30       # seconds
idle_timeout = 600         # seconds
max_lifetime = 1800        # seconds
```

### Session Configuration

```toml
[session]
secret = "your-session-secret-here"
cookie_name = "session_id"
cookie_secure = false      # Set to true in production with HTTPS
cookie_http_only = true
cookie_same_site = "lax"   # "strict", "lax", or "none"
max_age = 3600            # Session duration in seconds
```

### CORS Configuration

```toml
[cors]
allowed_origins = ["http://localhost:3030"]
allowed_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
allowed_headers = ["Content-Type", "Authorization"]
allow_credentials = true
max_age = 3600
```

### Security Configuration

```toml
[security]
enable_csrf = true
csrf_token_name = "csrf_token"
rate_limit_requests = 100  # Requests per window
rate_limit_window = 60     # Window size in seconds
bcrypt_cost = 12          # BCrypt hashing cost
```

### OAuth Configuration

```toml
[oauth]
enabled = true

[oauth.google]
client_id = "your-google-client-id"
client_secret = "your-google-client-secret"
redirect_uri = "http://localhost:3030/auth/google/callback"

[oauth.github]
client_id = "your-github-client-id"
client_secret = "your-github-client-secret"
redirect_uri = "http://localhost:3030/auth/github/callback"
```

### Email Configuration

```toml
[email]
# Enable/disable email functionality
enabled = true

# Email provider: "smtp", "sendgrid", or "console"
provider = "console"

# Default sender information
from_email = "noreply@yourapp.com"
from_name = "Your App Name"

# Template directory for internationalized email templates
template_dir = "templates/email"

# SMTP Configuration (when provider = "smtp")
smtp_host = "smtp.gmail.com"
smtp_port = 587
smtp_username = "your-email@gmail.com"
smtp_password = "your-app-password"
smtp_use_tls = false
smtp_use_starttls = true

# SendGrid Configuration (when provider = "sendgrid")
sendgrid_api_key = ""
sendgrid_endpoint = "https://api.sendgrid.com/v3/mail/send"

# Environment-specific email settings
[environments.development]
email.enabled = true
email.provider = "console"

[environments.production]
email.enabled = true
email.provider = "sendgrid"
email.sendgrid_api_key = "${SENDGRID_API_KEY}"
email.from_email = "noreply@yourdomain.com"
```

### Feature Flags

```toml
[features]
auth = true               # Enable authentication
tls = false              # Enable TLS support
content_db = true        # Enable database content management
two_factor_auth = false  # Enable 2FA
email = true             # Enable email functionality
```

## Environment Variable Overrides

Environment variables take precedence over TOML file values. Use the following format:

### Server Overrides
- `SERVER_PROTOCOL` → `server.protocol`
- `SERVER_HOST` → `server.host`
- `SERVER_PORT` → `server.port`
- `ENVIRONMENT` → `server.environment`
- `LOG_LEVEL` → `server.log_level`

### TLS Overrides
- `TLS_CERT_PATH` → `server.tls.cert_path`
- `TLS_KEY_PATH` → `server.tls.key_path`

### Database Overrides
- `DATABASE_URL` → `database.url`

### Session Overrides
- `SESSION_SECRET` → `session.secret`

### Example Environment Variables

```bash
# Server configuration
export SERVER_HOST="0.0.0.0"
export SERVER_PORT="8080"
export ENVIRONMENT="production"
export SERVER_PROTOCOL="https"

# Database
export DATABASE_URL="postgresql://prod_user:${DB_PASSWORD}@db.example.com:5432/prod_db"

# Security
export SESSION_SECRET="super-secret-production-key"
export TLS_CERT_PATH="/etc/ssl/certs/server.crt"
export TLS_KEY_PATH="/etc/ssl/private/server.key"

# OAuth
export GOOGLE_CLIENT_ID="your-google-client-id"
export GOOGLE_CLIENT_SECRET="your-google-client-secret"
export GITHUB_CLIENT_ID="your-github-client-id"
export GITHUB_CLIENT_SECRET="your-github-client-secret"

# Email
export EMAIL_PROVIDER="sendgrid"
export EMAIL_FROM_ADDRESS="noreply@yourdomain.com"
export EMAIL_FROM_NAME="Your Production App"
export SENDGRID_API_KEY="your-sendgrid-api-key"
export SMTP_HOST="smtp.gmail.com"
export SMTP_USERNAME="your-email@gmail.com"
export SMTP_PASSWORD="your-app-password"
```

## Environment Variable Substitution

You can use environment variable substitution in TOML files:

```toml
[database]
url = "postgresql://user:${DATABASE_PASSWORD}@localhost:5432/db"

[session]
secret = "${SESSION_SECRET}"

[oauth.google]
client_id = "${GOOGLE_CLIENT_ID}"
client_secret = "${GOOGLE_CLIENT_SECRET}"

[email]
provider = "${EMAIL_PROVIDER}"
from_email = "${EMAIL_FROM_ADDRESS}"
sendgrid_api_key = "${SENDGRID_API_KEY}"
smtp_password = "${SMTP_PASSWORD}"
```

## Usage in Code

### Loading Configuration

```rust
use server::config::Config;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load configuration
    let config = Config::load()?;
    
    // Use configuration
    println!("Server: {}:{}", config.server.host, config.server.port);
    println!("Database: {}", config.database.url);
    
    Ok(())
}
```

### Configuration Methods

```rust
let config = Config::load()?;

// Helper methods
let server_addr = config.server_address();      // "127.0.0.1:3030"
let server_url = config.server_url();           // "http://127.0.0.1:3030"
let is_dev = config.is_development();           // true/false
let is_prod = config.is_production();           // true/false
let needs_tls = config.requires_tls();          // true/false

// Database pool configuration
let pool_config = config.database_pool_config();

// Email configuration
let email_enabled = config.email.enabled;
let email_provider = &config.email.provider;
let template_dir = &config.email.template_dir;
```

### Custom Configuration

```rust
let custom_config = Config {
    server: ServerConfig {
        protocol: Protocol::Http,
        host: "localhost".to_string(),
        port: 3000,
        environment: Environment::Development,
        log_level: "debug".to_string(),
        tls: None,
    },
    app: AppConfig {
        name: "My App".to_string(),
        version: "1.0.0".to_string(),
        debug: true,
        ..Default::default()
    },
    ..Default::default()
};
```

## Best Practices

### Development

1. Use `config.dev.toml` for development settings
2. Enable debug logging and relaxed security
3. Use local database connections
4. Disable TLS for easier development

### Production

1. Use `config.prod.toml` for production settings
2. Enable all security features
3. Use environment variables for secrets
4. Enable TLS and secure cookies
5. Use restrictive CORS policies

### Security

1. **Never commit secrets to version control**
2. Use environment variables for sensitive data
3. Use strong session secrets (32+ characters)
4. Enable CSRF protection in production
5. Use secure cookies with HTTPS
6. Implement rate limiting

### Docker

```dockerfile
# Copy configuration files
COPY config.prod.toml /app/config.toml

# Set environment variables
ENV ENVIRONMENT=production
ENV DATABASE_URL=${DATABASE_URL}
ENV SESSION_SECRET=${SESSION_SECRET}
```

### Kubernetes

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  config.toml: |
    [server]
    protocol = "https"
    host = "0.0.0.0"
    port = 8080
    environment = "production"
    
    [database]
    url = "postgresql://user:${DATABASE_PASSWORD}@postgres:5432/app"
---
apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
data:
  DATABASE_PASSWORD: <base64-encoded-password>
  SESSION_SECRET: <base64-encoded-secret>
```

## Configuration Examples

### Development Environment

```toml
[server]
protocol = "http"
host = "127.0.0.1"
port = 3030
environment = "development"
log_level = "debug"

[database]
url = "postgresql://dev:dev@localhost:5432/app_dev"
max_connections = 5

[security]
enable_csrf = false
rate_limit_requests = 1000
bcrypt_cost = 4

[session]
cookie_secure = false
max_age = 7200

[email]
enabled = true
provider = "console"
template_dir = "templates/email"
```

### Production Environment

```toml
[server]
protocol = "https"
host = "0.0.0.0"
port = 443
environment = "production"
log_level = "info"

[server.tls]
cert_path = "/etc/ssl/certs/app.crt"
key_path = "/etc/ssl/private/app.key"

[database]
url = "postgresql://app:${DATABASE_PASSWORD}@db.example.com:5432/app_prod"
max_connections = 20

[security]
enable_csrf = true
rate_limit_requests = 50
bcrypt_cost = 12

[session]
secret = "${SESSION_SECRET}"
cookie_secure = true
cookie_same_site = "strict"
max_age = 3600

[email]
enabled = true
provider = "sendgrid"
sendgrid_api_key = "${SENDGRID_API_KEY}"
from_email = "noreply@yourdomain.com"
from_name = "Your Production App"
template_dir = "templates/email"
```

## Troubleshooting

### Configuration Not Found

```
Error: Configuration file not found: config.toml
```

**Solution:** Create a configuration file or set the `CONFIG_FILE` environment variable.

### Environment Variable Not Found

```
Error: Environment variable 'DATABASE_PASSWORD' not found
```

**Solution:** Set the required environment variable or remove the substitution from the TOML file.

### TLS Configuration Error

```
Error: TLS certificate path is required when using HTTPS
```

**Solution:** Either set `protocol = "http"` or provide valid TLS certificate paths.

### Database Connection Error

```
Error: Failed to connect to database
```

**Solution:** Check the database URL and ensure the database is running and accessible.

## Migration from Environment-Only Configuration

If you're migrating from a purely environment-based configuration:

1. Create a `config.toml` file with your current settings
2. Move sensitive values to environment variables
3. Use environment variable substitution in TOML
4. Test the configuration loading

Example migration:

```bash
# Old way (environment only)
export SERVER_HOST="0.0.0.0"
export SERVER_PORT="3030"
export DATABASE_URL="postgresql://..."

# New way (TOML + environment)
# config.toml
[server]
host = "0.0.0.0"
port = 3030

[database]
url = "${DATABASE_URL}"
```

## Testing Configuration

Run the configuration example to test your setup:

```bash
cargo run --example config_example
```

This will show you how your configuration is being loaded and what values are being used.

## Email Template Configuration

The email system uses an internationalized template structure with automatic language fallback:

### Template Directory Structure

```
templates/email/
├── en_/                    # English templates (default)
│   ├── html/              # HTML email templates
│   │   ├── contact.hbs    # Contact form template
│   │   └── notification.hbs # Notification template
│   └── text/              # Plain text templates
│       ├── contact.hbs
│       └── notification.hbs
├── es_/                   # Spanish templates
│   ├── html/
│   └── text/
└── README.md              # Template documentation
```

### Template Naming Convention

Templates are registered with the pattern: `{language}_{template_name}_{format}`

Examples:
- `en_contact_html` - English contact form HTML template
- `es_notification_text` - Spanish notification text template

### Language Detection and Fallback

The system automatically detects language preferences from:

1. **User Profile**: Authenticated user's saved language preference
2. **Request Headers**: `Accept-Language` HTTP header
3. **Default Fallback**: English (`en`)

### Template Configuration

```toml
[email]
# Template directory (relative to project root)
template_dir = "templates/email"

# Default language for fallback
default_language = "en"

# Supported languages
supported_languages = ["en", "es", "fr", "de"]
```

### Creating New Templates

1. **Create language directory:**
   ```bash
   mkdir -p templates/email/fr_/html
   mkdir -p templates/email/fr_/text
   ```

2. **Add template files:**
   ```bash
   # Create French contact template
   touch templates/email/fr_/html/contact.hbs
   touch templates/email/fr_/text/contact.hbs
   ```

3. **Template variables:**
   ```handlebars
   {{name}}          # User's name
   {{email}}         # User's email
   {{subject}}       # Message subject
   {{message}}       # Message content
   {{submitted_at}}  # Timestamp
   ```

### Available Handlebars Helpers

- `{{date_format submitted_at "%B %d, %Y at %I:%M %p UTC"}}`
- `{{capitalize form_type}}`
- `{{truncate user_agent 100}}`
- `{{default action_text "Click Here"}}`
- `{{url_encode email}}`

### Environment-Specific Email Settings

```toml
# Development - Print emails to console
[environments.development]
email.enabled = true
email.provider = "console"

# Staging - Use test SMTP server
[environments.staging]
email.enabled = true
email.provider = "smtp"
email.smtp_host = "smtp.mailtrap.io"
email.smtp_port = 2525

# Production - Use SendGrid
[environments.production]
email.enabled = true
email.provider = "sendgrid"
email.sendgrid_api_key = "${SENDGRID_API_KEY}"
```

For detailed email template documentation, see `templates/email/README.md`.

## Configuration Encryption System

The Rustelo framework includes a comprehensive encryption system for securing sensitive configuration values using AES-256-GCM encryption with automatic key management.

### Overview

The encryption system provides:
- **AES-256-GCM encryption** for sensitive configuration values
- **Automatic key generation** and management via `.k` file
- **Simple syntax** - encrypted values start with `@`
- **Automatic decryption** during configuration loading
- **CLI tools** for managing encrypted values
- **Environment variable compatibility** alongside encryption

### Quick Start

1. **Generate Encryption Key**:
   ```bash
   cargo run --bin config_crypto_tool generate-key
   ```

2. **Encrypt Sensitive Values**:
   ```bash
   cargo run --bin config_crypto_tool encrypt "my_secret_password"
   # Output: @AbCdEf123456...
   ```

3. **Use in Configuration**:
   ```toml
   [session]
   secret = "@AbCdEf123456..."
   
   [database]
   url = "postgresql://user:@ZW5jcnlwdGVk@localhost:5432/db"
   ```

4. **Verify Setup**:
   ```bash
   cargo run --bin config_crypto_tool verify
   ```

### Encryption Integration in Configuration

Configuration values starting with `@` are automatically decrypted during loading:

```toml
# config.prod.toml
[session]
secret = "@c2Vzc2lvbl9zZWNyZXRfZXhhbXBsZQ=="  # Encrypted session secret

[database]
url = "postgresql://user:@ZW5jcnlwdGVkX3Bhc3N3b3Jk@localhost:5432/mydb"

[oauth.google]
client_id = "${GOOGLE_CLIENT_ID}"  # Environment variable
client_secret = "@Z29vZ2xlX2NsaWVudF9zZWNyZXQ="  # Encrypted value

[email]
sendgrid_api_key = "@c2VuZGdyaWRfYXBpX2tleQ=="
smtp_password = "@c210cF9wYXNzd29yZA=="
```

### Mixed Configuration Approach

You can combine encrypted values with environment variables for maximum flexibility:

```toml
[database]
url = "${DATABASE_URL}"  # Environment variable (highest priority)

[session]
secret = "@encrypted_session_secret"  # Encrypted value

[oauth.google]
client_id = "${GOOGLE_CLIENT_ID}"  # Environment variable
client_secret = "@encrypted_google_secret"  # Encrypted value

[redis]
url = "@encrypted_redis_url"  # Encrypted Redis URL with credentials
```

### Configuration Loading Order

1. **Environment variables** (highest priority)
2. **Encrypted values** (decrypted automatically)
3. **Plain text values** (lowest priority)

The framework includes a built-in encryption system for securing sensitive configuration values using AES-256-GCM encryption.

### How It Works

1. **Encryption Key**: A `.k` file in the project root contains the encryption key
2. **Encrypted Values**: Configuration values starting with `@` are automatically decrypted
3. **Automatic Management**: The system handles key generation and value decryption seamlessly

### Quick Start

```bash
# Generate encryption key
cargo run --bin config_crypto_tool generate-key

# Encrypt a sensitive value
cargo run --bin config_crypto_tool encrypt "your_secret_value"
# Output: @AbCdEf123456...

# Use in configuration
echo 'session.secret = "@AbCdEf123456..."' >> config.toml

# Verify encryption works
cargo run --bin config_crypto_tool verify
```

### Configuration Examples

```toml
# Example encrypted configuration
[session]
secret = "@encrypted_session_secret"

[database]
url = "postgresql://user:@encrypted_password@localhost:5432/db"

[oauth.google]
client_secret = "@encrypted_google_client_secret"

[email]
sendgrid_api_key = "@encrypted_sendgrid_api_key"
smtp_password = "@encrypted_smtp_password"
```

### CLI Commands

```bash
# Key management
cargo run --bin config_crypto_tool generate-key       # Generate new key
cargo run --bin config_crypto_tool key-info          # Show key information
cargo run --bin config_crypto_tool verify            # Verify key works
cargo run --bin config_crypto_tool rotate-key --confirm  # Rotate key

# Value encryption/decryption
cargo run --bin config_crypto_tool encrypt "value"   # Encrypt a value
cargo run --bin config_crypto_tool decrypt "@..."    # Decrypt a value

# Configuration management
cargo run --bin config_crypto_tool find-encrypted -c config.toml
cargo run --bin config_crypto_tool show-decrypted -c config.toml
cargo run --bin config_crypto_tool encrypt-config -c config.toml -k "secret,api_key"

# Interactive mode
cargo run --bin config_crypto_tool interactive
```

### Security Features

- **AES-256-GCM encryption** with authenticated encryption
- **Automatic key generation** using cryptographically secure random numbers
- **File permissions** set to 0600 (read/write for owner only)
- **Key rotation support** with backup creation
- **Environment variable compatibility** - can mix encrypted and environment values

### Best Practices

1. **Never commit `.k` files** to version control
2. **Use different keys** for different environments
3. **Backup encryption keys** securely
4. **Rotate keys regularly** in production
5. **Monitor key file integrity**

### Mixed Configuration Approach

You can combine encrypted values with environment variables:

```toml
[database]
url = "${DATABASE_URL}"  # Environment variable

[session]
secret = "@encrypted_session_secret"  # Encrypted value

[oauth.google]
client_id = "${GOOGLE_CLIENT_ID}"  # Environment variable
client_secret = "@encrypted_google_secret"  # Encrypted value
```

### Deployment Considerations

```bash
# Production deployment
# 1. Generate key on production server
cargo run --bin config_crypto_tool generate-key

# 2. Encrypt production secrets
PROD_SECRET=$(cargo run --bin config_crypto_tool encrypt "prod-secret-2024")

# 3. Update configuration with encrypted values
# 4. Ensure .k file is properly secured and backed up
```

### File Structure

```
project/
├── .k                    # Encryption key (DO NOT COMMIT)
├── config.prod.toml      # Config with encrypted values
├── .gitignore           # Must include .k
└── docs/
    └── ENCRYPTION.md    # Detailed encryption documentation
```

### Error Handling

Common issues and solutions:

- **Key not found**: Run `cargo run --bin config_crypto_tool generate-key`
- **Decryption failed**: Verify key with `cargo run --bin config_crypto_tool verify`
- **Permission denied**: Set proper permissions with `chmod 600 .k`

For comprehensive encryption documentation, see `docs/ENCRYPTION.md`.