"""
性能监控中间件

监控请求处理时间、数据库查询性能等
""" 
import logging
import time
from typing import Callable
from fastapi import Request, Response
from starlette.middleware.base import BaseHTTPMiddleware
from prometheus_client import Histogram, Counter

logger = logging.getLogger(__name__)

request_payload_size = Histogram(
    'http_request_payload_bytes',
    'HTTP request payload size in bytes',
    ['method', 'endpoint']
)

response_payload_size = Histogram(
    'http_response_payload_bytes',
    'HTTP response payload size in bytes',
    ['method', 'endpoint', 'status']
)

slow_requests_total = Counter(
    'http_slow_requests_count',
    'Total number of slow requests (>1s)',
    ['method', 'endpoint']
)


class PerformanceMonitoringMiddleware(BaseHTTPMiddleware):
    """性能监控中间件
    
    监控和记录请求性能指标
    """
    
    def __init__(self, app, slow_request_threshold: float = 1.0):
        """
        Args:
            app: FastAPI application
            slow_request_threshold: 慢请求阈值（秒）
        """
        super().__init__(app)
        self.slow_request_threshold = slow_request_threshold
    
    async def dispatch(self, request: Request, call_next: Callable) -> Response:
        """处理请求并记录性能指标"""
        # 记录开始时间
        start_time = time.time()
        
        # 获取请求信息
        method = request.method
        path = request.url.path
        
        # 简化路径（移除 ID 等动态部分）
        endpoint = self._normalize_path(path)
        
        # 记录请求大小
        request_size = int(request.headers.get('content-length', 0))
        if request_size > 0:
            request_payload_size.labels(method=method, endpoint=endpoint).observe(request_size)
        
        # 处理请求
        response = await call_next(request)
        
        # 计算处理时间
        duration = time.time() - start_time
        
        # 记录响应大小
        response_size = int(response.headers.get('content-length', 0))
        if response_size > 0:
            response_payload_size.labels(
                method=method,
                endpoint=endpoint,
                status=response.status_code
            ).observe(response_size)
        
        # 检查是否为慢请求
        if duration > self.slow_request_threshold:
            slow_requests_total.labels(method=method, endpoint=endpoint).inc()
            logger.warning(
                f"Slow request detected: {method} {path}",
                extra={
                    'extra_fields': {
                        'duration': duration,
                        'threshold': self.slow_request_threshold,
                        'method': method,
                        'path': path,
                        'status_code': response.status_code
                    }
                }
            )
        
        # 添加性能头
        response.headers['X-Process-Time'] = f"{duration:.3f}"
        
        return response
    
    def _normalize_path(self, path: str) -> str:
        """标准化路径，移除动态部分
        
        例如：/api/projects/123 -> /api/projects/{id}
        """
        parts = path.split('/')
        normalized_parts = []
        
        for part in parts:
            # 检查是否为 UUID 或数字 ID
            if self._is_id(part):
                normalized_parts.append('{id}')
            else:
                normalized_parts.append(part)
        
        return '/'.join(normalized_parts)
    
    def _is_id(self, part: str) -> bool:
        """检查是否为 ID"""
        if not part:
            return False
        
        # 检查是否为 UUID
        if len(part) == 36 and part.count('-') == 4:
            return True
        
        # 检查是否为纯数字
        if part.isdigit():
            return True
        
        return False


def setup_performance_monitoring(app, slow_request_threshold: float = 1.0):
    """设置性能监控中间件
    
    Args:
        app: FastAPI application
        slow_request_threshold: 慢请求阈值（秒）
    """
    app.add_middleware(
        PerformanceMonitoringMiddleware,
        slow_request_threshold=slow_request_threshold
    )
    logger.info(f"Performance monitoring middleware enabled (slow threshold: {slow_request_threshold}s)")
