from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from loguru import logger
import uvicorn
from datetime import datetime, timedelta
from typing import List, Dict
import asyncio

from src.monitors.gpu_monitor import GPUMonitor
from src.monitors.cooling_monitor import CoolingMonitor
from src.config.config import settings
from src.utils.influxdb_client import InfluxDBManager

app = FastAPI()

# CORS 설정
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 모니터 초기화
gpu_monitor = GPUMonitor()
cooling_monitor = CoolingMonitor()
influxdb_manager = InfluxDBManager()

async def collect_metrics():
    """주기적으로 메트릭을 수집하고 저장합니다."""
    while True:
        try:
            # GPU 메트릭 수집 및 저장
            gpu_info = gpu_monitor.get_gpu_info()
            for gpu in gpu_info:
                influxdb_manager.write_gpu_metrics(gpu)
            
            # 냉각 시스템 메트릭 수집 및 저장
            cooling_info = cooling_monitor.get_temperature_info()
            influxdb_manager.write_cooling_metrics(cooling_info)
            
            logger.info("메트릭 수집 및 저장 완료")
        except Exception as e:
            logger.error(f"메트릭 수집 중 오류 발생: {str(e)}")
        
        # 1분마다 수집
        await asyncio.sleep(60)

@app.on_event("startup")
async def startup_event():
    """서버 시작 시 메트릭 수집 태스크 시작"""
    asyncio.create_task(collect_metrics())

@app.get("/api/gpu/status")
async def get_gpu_status():
    try:
        gpu_info = gpu_monitor.get_gpu_info()
        return gpu_info
    except Exception as e:
        logger.error(f"GPU 상태 조회 중 오류 발생: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/api/cooling/status")
async def get_cooling_status():
    try:
        cooling_info = cooling_monitor.get_temperature_info()
        return cooling_info
    except Exception as e:
        logger.error(f"냉각 시스템 상태 조회 중 오류 발생: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/api/metrics/history")
async def get_metrics_history(hours: int = 24):
    try:
        metrics = influxdb_manager.get_metrics_history(hours)
        return metrics
    except Exception as e:
        logger.error(f"메트릭 히스토리 조회 중 오류 발생: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/api/alerts")
async def get_alerts():
    try:
        # GPU 알림 조회
        gpu_alerts = gpu_monitor.check_gpu_status()
        
        # 냉각 시스템 알림 조회
        cooling_alerts = cooling_monitor.check_cooling_status()
        
        # 모든 알림 수집
        all_alerts = []
        
        # GPU 알림에 타임스탬프 추가
        for alert in gpu_alerts:
            alert['timestamp'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            all_alerts.append(alert)
        
        # 냉각 시스템 알림에 타임스탬프 추가
        for alert in cooling_alerts:
            alert['timestamp'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            all_alerts.append(alert)
        
        return all_alerts
    except Exception as e:
        logger.error(f"알림 조회 중 오류 발생: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8004) 