// Archive Configuration - User Configurable Options

use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::path::Path;

/// Archive Configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ArchiveConfig {
    // Optional formats (controversial)
    pub enable_rar: bool,    // ⚠️ Legal risk (RARLAB patent)
    pub enable_xz: bool,     // ⚠️ External dependency (liblzma)
    pub enable_7z: bool,     // ⚠️ Unstable library
    
    // Performance settings
    pub cache_size_mb: u64,
    pub max_concurrent_extractions: usize,
    
    // Security settings
    pub max_decompression_ratio: u64,
    pub max_file_size_mb: u64,
}

impl Default for ArchiveConfig {
    fn default() -> Self {
        Self {
            // Optional formats (default disabled)
            enable_rar: false,
            enable_xz: false,
            enable_7z: false,
            
            // Performance
            cache_size_mb: 100,
            max_concurrent_extractions: 4,
            
            // Security
            max_decompression_ratio: 1000,
            max_file_size_mb: 1024,
        }
    }
}

impl ArchiveConfig {
    /// Load configuration from TOML file
    pub fn load(path: &str) -> Result<Self> {
        let content = std::fs::read_to_string(path)?;
        let config: ArchiveConfig = toml::from_str(&content)?;
        
        // Validate configuration
        config.validate()?;
        
        Ok(config)
    }
    
    /// Save configuration to TOML file
    pub fn save(&self, path: &str) -> Result<()> {
        let content = toml::to_string_pretty(self)?;
        std::fs::write(path, content)?;
        Ok(())
    }
    
    /// Validate configuration
    pub fn validate(&self) -> Result<()> {
        if self.cache_size_mb > 1000 {
            warn!("Cache size > 1GB may cause memory pressure");
        }
        
        if self.max_concurrent_extractions > 10 {
            warn!("Concurrent extractions > 10 may cause resource exhaustion");
        }
        
        if self.max_decompression_ratio < 10 {
            return Err(anyhow::anyhow!("Max decompression ratio too low (min 10)"));
        }
        
        if self.max_file_size_mb > 10_000 {  // 10GB
            warn!("Max file size > 10GB may cause disk space issues");
        }
        
        Ok(())
    }
    
    /// Generate default config file template
    pub fn generate_template() -> String {
        let config = Self::default();
        
        format!(
            "# === Archive Configuration ===
# MarkBase Universal Compression Format Support

[archive]
# === Optional Formats (Default Disabled) ===

# ⚠️ RAR Format Legal Risk Warning
# - RAR compression algorithm is patented by RARLAB
# - Commercial use requires license (approx $1000+)
# - unrar library only supports decompression, no compression
# - User assumes all legal risks by enabling
# - License info: https://rarlab.com/license.htm
enable_rar = false

# ⚠️ XZ Format External Dependency Warning
# - XZ format requires external liblzma library
# - macOS: brew install xz
# - Linux: apt install liblzma-dev
# - Windows: manual installation required
# - XZ disabled if liblzma not found
enable_xz = false

# ⚠️ 7z Format Library Stability Warning
# - sevenz-rust library (v0.21.0) under development
# - Some compression algorithms not supported
# - Production stability limited
enable_7z = false

# === Performance Settings ===
cache_size_mb = {}              # Decompression cache size
max_concurrent_extractions = {} # Max concurrent extractions

# === Security Settings ===
max_decompression_ratio = {}    # Zip Bomb protection (ratio limit)
max_file_size_mb = {}           # File size limit (MB)

# === Core Formats (Always Enabled) ===
# ZIP, TAR, GZIP, ZSTD, BZIP2, LZ4
# Composite: TAR.GZ, TAR.BZ2, TAR.ZST
# Total: 9 formats, covering 80%+ scenarios
",
            config.cache_size_mb,
            config.max_concurrent_extractions,
            config.max_decompression_ratio,
            config.max_file_size_mb
        )
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_default_config() {
        let config = ArchiveConfig::default();
        
        assert_eq!(config.enable_rar, false);
        assert_eq!(config.enable_xz, false);
        assert_eq!(config.enable_7z, false);
        assert_eq!(config.cache_size_mb, 100);
        assert_eq!(config.max_decompression_ratio, 1000);
    }
    
    #[test]
    fn test_config_validation() {
        let config = ArchiveConfig {
            max_decompression_ratio: 5,
            ..Default::default()
        };
        
        assert!(config.validate().is_err());
    }
    
    #[test]
    fn test_config_template() {
        let template = ArchiveConfig::generate_template();
        
        assert!(template.contains("enable_rar = false"));
        assert!(template.contains("⚠️ RAR Format Legal Risk Warning"));
    }
}