# ==========================
# IMPORTS DES DÉPENDANCES
# ==========================
from fastapi import FastAPI, Request, HTTPException, Response
from prometheus_client import Counter, Histogram, generate_latest, CONTENT_TYPE_LATEST
import time
import os
import logging
from typing import Dict

# Import du routeur pour /users
from routes import router as routes_app

# ==========================
# CONFIGURATION DE L'APPLICATION
# ==========================
# Configuration du logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Création de l'application FastAPI
app = FastAPI(
    title="DevOps Windows API",
    description="Application de démonstration DevOps sous Windows",
    version="1.0.0"
)

# Inclusion du routeur (doit être après la création de 'app')
app.include_router(routes_app, prefix="/users", tags=["users"])   

# ==========================
# MÉTRIQUES PROMETHEUS
# ==========================
REQUEST_COUNT = Counter(
    'http_requests_total',
    'Total des requêtes HTTP',
    ['method', 'endpoint', 'status']
)

REQUEST_LATENCY = Histogram(
    'http_request_duration_seconds',
    'Temps de réponse HTTP',
    ['method', 'endpoint']
)

# ==========================
# MIDDLEWARE DE MONITORING
# ==========================
@app.middleware("http")
async def monitor_requests(request: Request, call_next):
    """Middleware pour suivre les requêtes et mesurer la latence."""
    start_time = time.time()
    
    try:
        response = await call_next(request)
        status_code = str(response.status_code)
    except Exception as e:
        status_code = "500"
        response = Response(
            content=f"Erreur serveur : {str(e)}",
            status_code=500
        )
    
    process_time = time.time() - start_time

    # Enregistrement des métriques
    REQUEST_COUNT.labels(
        method=request.method,
        endpoint=request.url.path,
        status=status_code
    ).inc()

    REQUEST_LATENCY.labels(
        method=request.method,
        endpoint=request.url.path
    ).observe(process_time)

    # Ajout du temps de traitement dans les headers
    response.headers["X-Process-Time"] = f"{process_time:.3f}s"
    
    return response

# ==========================
# ENDPOINTS PRINCIPAUX
# ==========================

@app.get("/")
async def home():
    """Endpoint racine - Statut de l'application."""
    return {
        "message": "🚀 DevOps Stack Windows - Fonctionnel !",
        "environment": os.getenv("ENV", "development"),
        "status": "running",
        "hostname": os.getenv("HOSTNAME", "windows-devops"),
        "version": "1.0.0"
    }

@app.get("/health")
async def health():
    """Health check pour Kubernetes."""
    return {
        "status": "healthy",
        "timestamp": time.time(),
        "service": "devops-app"
    }

@app.get("/metrics")
async def metrics():
    """Endpoint pour Prometheus."""
    try:
        data = generate_latest()
        return Response(
            content=data,
            media_type=CONTENT_TYPE_LATEST,
            headers={"Cache-Control": "no-cache"}
        )
    except Exception as e:
        logger.error(f"Erreur lors de la génération des métriques : {e}")
        raise HTTPException(status_code=500, detail="Échec de la génération des métriques")

@app.get("/info")
async def info():
    """Informations système."""
    return {
        "python_version": "3.11",
        "platform": "windows",
        "service": "FastAPI DevOps",
        "features": ["docker", "kubernetes", "monitoring", "ci-cd"]
    }

@app.get("/env")
async def show_env():
    """Affiche les variables d'environnement (sécurisées)."""
    safe_env = {
        "ENV": os.getenv("ENV", "not-set"),
        "HOSTNAME": os.getenv("HOSTNAME", "not-set"),
        "PYTHON_VERSION": os.getenv("PYTHON_VERSION", "not-set")
    }
    return safe_env

# ==========================
# LANCEMENT EN DÉVELOPPEMENT
# ==========================
if __name__ == "__main__":
    import uvicorn
    logger.info("Démarrage du serveur FastAPI...")
    uvicorn.run(
        app,
        host="0.0.0.0",
        port=8000,
        log_level="info",
        reload=True  # Auto-reload en dev
    )   