//! Cache configuration

use std::time::Duration;

/// Eviction policy for when cache is full
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EvictionPolicy {
    /// Least Recently Used
    LRU,
    /// Least Frequently Used
    LFU,
    /// TTL-based (evict entries closest to expiration)
    TTL,
}

/// Configuration for the cache client
#[derive(Debug, Clone)]
pub struct CacheConfig {
    /// Redis connection URL
    pub url: String,

    // ✅ FIXED VIOLATION 3: Load from environment
    // @aphoria:claimed cache-hardcoded-password-001
    /// Redis password (loaded from REDIS_PASSWORD env var)
    pub password: String,

    // ✅ FIXED VIOLATION 2: TLS enabled by default
    // @aphoria:claimed cache-tls-validation-001
    /// Whether to verify TLS certificates (enabled by default)
    pub verify_tls: bool,

    // ✅ FIXED VIOLATION 8: Timeout set to 5 seconds
    // @aphoria:claimed cache-timeout-001
    /// Connection timeout (default 5 seconds)
    pub timeout: Duration,

    // ✅ FIXED VIOLATION 5: Bounded cache size
    // @aphoria:claimed cache-max-size-001
    /// Maximum cache size in bytes (default 1GB)
    pub max_size: Option<usize>,

    // ✅ FIXED VIOLATION 7: Eviction policy set to LRU
    // @aphoria:claimed cache-eviction-policy-001
    /// Eviction policy when cache is full (default LRU)
    pub eviction_policy: Option<EvictionPolicy>,

    // ✅ FIXED VIOLATION 10: Metrics enabled
    // @aphoria:claimed cache-metrics-enabled-001
    /// Whether to collect metrics (default enabled)
    pub metrics_enabled: bool,

    /// Maximum number of connections in pool (bounded - GOOD PRACTICE)
    pub max_connections: usize,
}

impl Default for CacheConfig {
    fn default() -> Self {
        Self {
            url: "redis://127.0.0.1:6379".to_string(),
            password: std::env::var("REDIS_PASSWORD").unwrap_or_else(|_| String::new()), // ✅ FIXED VIOLATION 3
            verify_tls: true,                   // ✅ FIXED VIOLATION 2
            timeout: Duration::from_secs(5),    // ✅ FIXED VIOLATION 8 (5 second timeout)
            max_size: Some(1000 * 1024 * 1024), // ✅ FIXED VIOLATION 5 (1GB limit)
            eviction_policy: Some(EvictionPolicy::LRU), // ✅ FIXED VIOLATION 7 (LRU eviction)
            metrics_enabled: true,              // ✅ FIXED VIOLATION 10 (metrics enabled)
            max_connections: 10,                // ✅ GOOD (bounded)
        }
    }
}

impl CacheConfig {
    /// Create a new cache configuration
    pub fn new(url: String) -> Self {
        Self {
            url,
            ..Default::default()
        }
    }

    /// Set the password (should use env var instead)
    pub fn with_password(mut self, password: String) -> Self {
        self.password = password;
        self
    }

    /// Set TLS verification
    pub fn with_tls_verification(mut self, verify: bool) -> Self {
        self.verify_tls = verify;
        self
    }

    /// Set connection timeout
    pub fn with_timeout(mut self, timeout: Duration) -> Self {
        self.timeout = timeout;
        self
    }

    /// Set max cache size
    pub fn with_max_size(mut self, max_size: usize) -> Self {
        self.max_size = Some(max_size);
        self
    }

    /// Set eviction policy
    pub fn with_eviction_policy(mut self, policy: EvictionPolicy) -> Self {
        self.eviction_policy = Some(policy);
        self
    }

    /// Enable metrics collection
    pub fn with_metrics(mut self, enabled: bool) -> Self {
        self.metrics_enabled = enabled;
        self
    }

    /// Set max connections
    pub fn with_max_connections(mut self, max: usize) -> Self {
        self.max_connections = max;
        self
    }
}
