import time
import functools
import statistics
from typing import List, Callable, Any

class PerformanceMonitor:
    """
    모니터링 및 SLO 측정 엔진 (Phase 3: Monitoring Integration)
    모든 병목 지점에 타이밍 래퍼를 삽입하여 실시간 가시성 확보.
    """
    
    def __init__(self):
        self.latencies: List[float] = []
        self.slo_threshold_ms = 200.0 # P95 목표: 200ms 이하

    def track_latency(self, func: Callable):
        """메서드 실행 시간을 측정하는 데코레이터"""
        @functools.wraps(func)
        async def wrapper(*args, **kwargs):
            start_time = time.perf_counter()
            result = await func(*args, **kwargs) if asyncio.iscoroutinefunction(func) else func(*args, **kwargs)
            latency = (time.perf_counter() - start_time) * 1000
            
            self.latencies.append(latency)
            if latency > self.slo_threshold_ms:
                print(f"[SLO Alert] {func.__name__} violated SLO! Latency: {latency:.2f}ms (Goal: {self.slo_threshold_ms}ms)")
            
            return result
        return wrapper

    def get_stats(self) -> dict:
        """현재까지의 지연 시간 통계 산출 (P95 포함)"""
        if not self.latencies:
            return {"count": 0}
            
        stats = {
            "count": len(self.latencies),
            "avg_ms": statistics.mean(self.latencies),
            "max_ms": max(self.latencies),
            "p95_ms": statistics.quantiles(self.latencies, n=20)[18] if len(self.latencies) >= 20 else "N/A"
        }
        return stats

    def report(self):
        """정기 성능 보고서 출력"""
        stats = self.get_stats()
        print("\n" + "="*40)
        print("📊 [SYSTEM PERFORMANCE REPORT]")
        print(f"Total Requests: {stats['count']}")
        print(f"Average Latency: {stats.get('avg_ms', 0):.2f}ms")
        print(f"P95 Latency: {stats['p95_ms']}")
        print("="*40 + "\n")

monitor = PerformanceMonitor()

import asyncio # for decorator awareness
