SHELL := /bin/bash
PY ?= .venv/bin/python
SLUG := otel
COMPOSE := docker compose -p lab-$(SLUG)
# Ne PAS faire `-include .env` + `export` : .env écraserait les variables passées en ligne de commande.
# docker compose et les scripts Python lisent .env eux-mêmes.
export PYTHONPATH := src

.DEFAULT_GOAL := help
help: ## Liste les commandes
	@grep -hE '^[a-z0-9-]+:.*## ' Makefile | awk -F':.*## ' '{printf "  make %-14s %s\n", $$1, $$2}'

setup: ## Crée .venv, installe les dépendances, crée .env (mot de passe Grafana aléatoire)
	@test -d .venv || python3 -m venv .venv
	@.venv/bin/pip install -q -r requirements.txt
	@if [ ! -f .env ]; then cp .env.example .env; \
	  sed -i "s|^GRAFANA_ADMIN_PASSWORD=changeme|GRAFANA_ADMIN_PASSWORD=$$(openssl rand -hex 16)|" .env; \
	  echo ".env créé. Ajoutez GEMINI_API_KEY, ou mettez FAUX_MODELE=1 pour tout tester gratuitement."; fi
	@echo "Prêt. Ensuite : make test, puis make up"

test: ## Tests sans clé ni réseau (instrumentation, coûts, cache, tableau de bord, alertes)
	@$(PY) -m pytest -q tests

up: ## Démarre collecteur, Prometheus, Tempo, Loki, Grafana (http://localhost:3300)
	@$(COMPOSE) up -d
	@echo -n "Attente de Grafana"; for i in $$(seq 1 60); do curl -sf http://127.0.0.1:3300/api/health >/dev/null && { echo " : prêt. http://localhost:3300 (admin / GRAFANA_ADMIN_PASSWORD de .env)"; exit 0; }; echo -n "."; sleep 2; done; echo " : délai dépassé"; exit 1

run: ## Lance le service sur http://127.0.0.1:8088 (Ctrl+C pour arrêter)
	@$(PY) -m uvicorn assistant_obs.app:app --port 8088

charge: ## Envoie 120 requêtes au service lancé par make run
	@$(PY) -m assistant_obs.charge --requetes 120 --concurrence 4

e2e: ## Test réel : service + charge + vérification Prometheus, Tempo, Loki, Grafana
	@$(PY) -m assistant_obs.e2e

demo-alerte: ## Sans clé : faux modèle à 30 % d'erreurs pendant 4 min, pour voir l'alerte se déclencher
	@FAUX_MODELE=1 TAUX_ERREUR_FAUX=0.3 E2E_REQUETES=1500 CACHE_TTL_S=0 $(PY) -m assistant_obs.e2e

valider-gcp: ## Valide la configuration du collecteur pour Google Cloud (sans rien envoyer)
	@docker run --rm -e GOOGLE_CLOUD_PROJECT=lab-exemple -v $$PWD/otel:/cfg otel/opentelemetry-collector-contrib:0.161.0 validate --config=/cfg/collector-gcp.yaml && echo "collector-gcp.yaml valide"

down: ## Arrête la pile ET supprime ses volumes
	@$(COMPOSE) down -v --remove-orphans
	@left=$$(docker volume ls -q --filter label=com.docker.compose.project=lab-$(SLUG)); \
	  if [ -n "$$left" ]; then echo "Volumes restants : $$left"; exit 1; else echo "Pile et volumes lab-$(SLUG) supprimés."; fi

clean: down ## Supprime artefacts locaux et pile Docker
	@rm -rf .pytest_cache tests/__pycache__ src/assistant_obs/__pycache__
	@echo "Artefacts supprimés."

reset: clean ## clean + supprime .venv (garde .env)
	@rm -rf .venv
	@echo "Environnement supprimé (.env conservé)."

cloud-up: ## Sans objet : la cible GCP est décrite (leçon 6), pas créée
	@echo "Aucune ressource Google Cloud créée par ce projet. Voir otel/collector-gcp.yaml et make valider-gcp."
cloud-down: ## Sans objet
	@echo "Aucune ressource Google Cloud à supprimer."
cloud-status: ## Sans objet
	@echo "Aucune ressource Google Cloud créée par ce projet."
