#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
壓縮配置管理器
==============

管理 Web UI 的 Gzip 壓縮配置和靜態文件緩存策略。
支援可配置的壓縮參數和性能優化選項。
"""

import os
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass
from pathlib import Path


@dataclass
class CompressionConfig:
    """壓縮配置類"""
    
    # Gzip 壓縮設定
    minimum_size: int = 1000  # 最小壓縮大小（bytes）
    compression_level: int = 6  # 壓縮級別 (1-9, 6為平衡點)
    
    # 緩存設定
    static_cache_max_age: int = 3600  # 靜態文件緩存時間（秒）
    api_cache_max_age: int = 0  # API 響應緩存時間（秒，0表示不緩存）
    
    # 支援的 MIME 類型
    compressible_types: List[str] = None
    
    # 排除的路徑
    exclude_paths: List[str] = None
    
    def __post_init__(self):
        """初始化後處理"""
        if self.compressible_types is None:
            self.compressible_types = [
                'text/html',
                'text/css', 
                'text/javascript',
                'text/plain',
                'application/json',
                'application/javascript',
                'application/xml',
                'application/rss+xml',
                'application/atom+xml',
                'image/svg+xml'
            ]
        
        if self.exclude_paths is None:
            self.exclude_paths = [
                '/ws',  # WebSocket 連接
                '/api/ws',  # WebSocket API
                '/health',  # 健康檢查
            ]
    
    @classmethod
    def from_env(cls) -> 'CompressionConfig':
        """從環境變數創建配置"""
        return cls(
            minimum_size=int(os.getenv('MCP_GZIP_MIN_SIZE', '1000')),
            compression_level=int(os.getenv('MCP_GZIP_LEVEL', '6')),
            static_cache_max_age=int(os.getenv('MCP_STATIC_CACHE_AGE', '3600')),
            api_cache_max_age=int(os.getenv('MCP_API_CACHE_AGE', '0'))
        )
    
    def should_compress(self, content_type: str, content_length: int) -> bool:
        """判斷是否應該壓縮"""
        if content_length < self.minimum_size:
            return False
        
        if not content_type:
            return False
        
        # 檢查 MIME 類型
        for mime_type in self.compressible_types:
            if content_type.startswith(mime_type):
                return True
        
        return False
    
    def should_exclude_path(self, path: str) -> bool:
        """判斷路徑是否應該排除壓縮"""
        for exclude_path in self.exclude_paths:
            if path.startswith(exclude_path):
                return True
        return False
    
    def get_cache_headers(self, path: str) -> Dict[str, str]:
        """獲取緩存頭"""
        headers = {}
        
        if path.startswith('/static/'):
            # 靜態文件緩存
            headers['Cache-Control'] = f'public, max-age={self.static_cache_max_age}'
            headers['Expires'] = self._get_expires_header(self.static_cache_max_age)
        elif path.startswith('/api/') and self.api_cache_max_age > 0:
            # API 緩存（如果啟用）
            headers['Cache-Control'] = f'public, max-age={self.api_cache_max_age}'
            headers['Expires'] = self._get_expires_header(self.api_cache_max_age)
        else:
            # 其他路徑不緩存
            headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
            headers['Pragma'] = 'no-cache'
            headers['Expires'] = '0'
        
        return headers
    
    def _get_expires_header(self, max_age: int) -> str:
        """生成 Expires 頭"""
        from datetime import datetime, timedelta
        expires_time = datetime.utcnow() + timedelta(seconds=max_age)
        return expires_time.strftime('%a, %d %b %Y %H:%M:%S GMT')
    
    def get_compression_stats(self) -> Dict[str, any]:
        """獲取壓縮配置統計"""
        return {
            'minimum_size': self.minimum_size,
            'compression_level': self.compression_level,
            'static_cache_max_age': self.static_cache_max_age,
            'compressible_types_count': len(self.compressible_types),
            'exclude_paths_count': len(self.exclude_paths),
            'compressible_types': self.compressible_types,
            'exclude_paths': self.exclude_paths
        }


class CompressionManager:
    """壓縮管理器"""
    
    def __init__(self, config: Optional[CompressionConfig] = None):
        self.config = config or CompressionConfig.from_env()
        self._stats = {
            'requests_total': 0,
            'requests_compressed': 0,
            'bytes_original': 0,
            'bytes_compressed': 0,
            'compression_ratio': 0.0
        }
    
    def update_stats(self, original_size: int, compressed_size: int, was_compressed: bool):
        """更新壓縮統計"""
        self._stats['requests_total'] += 1
        self._stats['bytes_original'] += original_size
        
        if was_compressed:
            self._stats['requests_compressed'] += 1
            self._stats['bytes_compressed'] += compressed_size
        else:
            self._stats['bytes_compressed'] += original_size
        
        # 計算壓縮比率
        if self._stats['bytes_original'] > 0:
            self._stats['compression_ratio'] = (
                1 - self._stats['bytes_compressed'] / self._stats['bytes_original']
            ) * 100
    
    def get_stats(self) -> Dict[str, any]:
        """獲取壓縮統計"""
        stats = self._stats.copy()
        stats['compression_percentage'] = (
            self._stats['requests_compressed'] / max(self._stats['requests_total'], 1) * 100
        )
        return stats
    
    def reset_stats(self):
        """重置統計"""
        self._stats = {
            'requests_total': 0,
            'requests_compressed': 0,
            'bytes_original': 0,
            'bytes_compressed': 0,
            'compression_ratio': 0.0
        }


# 全域壓縮管理器實例
_compression_manager: Optional[CompressionManager] = None


def get_compression_manager() -> CompressionManager:
    """獲取全域壓縮管理器實例"""
    global _compression_manager
    if _compression_manager is None:
        _compression_manager = CompressionManager()
    return _compression_manager
