SHELL := /bin/bash
PY ?= .venv/bin/python
SLUG := k8s-ia
CLUSTER := lab-$(SLUG)
CTX := kind-$(CLUSTER)
NS := assistant
RELEASE := inference
TAG ?= 0.1.0
IMAGE := lab-k8s-ia/inference
HTTP_PORT := 8081
URL := http://assistant.127.0.0.1.nip.io:$(HTTP_PORT)
INGRESS_NGINX := https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.15.1/deploy/static/provider/kind/deploy.yaml
METRICS_SERVER := https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.9.0/components.yaml
K := kubectl --context $(CTX)
H := helm --kube-context $(CTX)
.PHONY: help setup test run up cluster addons image secret deploy e2e load status down clean reset cloud-up cloud-down cloud-status
.DEFAULT_GOAL := help
help: ## Liste les commandes
	@grep -hE '^[a-z0-9-]+:.*## ' Makefile | awk -F':.*## ' '{printf "  make %-13s %s\n", $$1, $$2}'

setup: ## Crée .venv et installe les dépendances
	@test -d .venv || python3 -m venv .venv
	@.venv/bin/pip install -q -r requirements-dev.txt
	@test -f .env || cp .env.example .env
	@echo "Prêt. Renseignez .env puis : make test"

test: ## Tests sans clé ni réseau (API + rendu du chart)
	@$(PY) -m pytest -q

run: ## Lance l'API en local (http://localhost:8000), variables lues dans .env
	@$(PY) -m uvicorn app.main:app --port 8000 --env-file .env

up: cluster addons image secret deploy ## Cluster kind + Ingress + metrics-server + image + Secret + chart
	@echo "Ouvrez $(URL)"

cluster:
	@kind get clusters 2>/dev/null | grep -qx $(CLUSTER) || kind create cluster --name $(CLUSTER) --config k8s/kind-config.yaml --wait 120s

addons:
	@$(K) apply -f $(INGRESS_NGINX) >/dev/null
	@$(K) apply -f $(METRICS_SERVER) >/dev/null
	@# kind : les kubelets ont des certificats auto-signés.
	@$(K) -n kube-system patch deploy metrics-server --type=json \
	  -p '[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]' >/dev/null 2>&1 || true
	@$(K) -n ingress-nginx rollout status deploy/ingress-nginx-controller --timeout=180s
	@$(K) -n kube-system rollout status deploy/metrics-server --timeout=180s

image: ## Construit l'image TAG et la charge dans kind
	@docker build -q -t $(IMAGE):$(TAG) . >/dev/null
	@kind load docker-image $(IMAGE):$(TAG) --name $(CLUSTER) >/dev/null
	@echo "Image $(IMAGE):$(TAG) chargée dans $(CLUSTER)"

secret: ## Crée/actualise le Secret de la clé (jamais dans le chart)
	@$(K) create namespace $(NS) --dry-run=client -o yaml | $(K) apply -f - >/dev/null
	@# .env n'est ni inclus ni exporté : la clé est lue ici seulement (une variable d'environnement l'emporte).
	@KEY="$${GEMINI_API_KEY:-$$(sed -n 's/^GEMINI_API_KEY=//p' .env 2>/dev/null)}"; \
	 test -n "$$KEY" && test "$$KEY" != "remplacez-moi" || { echo "GEMINI_API_KEY absente de .env"; exit 1; }; \
	 printf '%s' "$$KEY" | $(K) -n $(NS) create secret generic inference-gemini \
	  --from-file=GEMINI_API_KEY=/dev/stdin --dry-run=client -o yaml | $(K) apply -f - >/dev/null
	@echo "Secret inference-gemini à jour dans $(NS)"

deploy: ## helm upgrade --install (image TAG, options dans VALUES="--set ...")
	@$(H) upgrade --install $(RELEASE) chart/inference -n $(NS) --create-namespace \
	  --set image.tag=$(TAG) $(VALUES) --wait --timeout 3m

e2e: ## Test réel sur le cluster : Gemini via l'Ingress, non-root, NetworkPolicy
	@IMAGE=$(IMAGE):$(TAG) KCTX=$(CTX) NS=$(NS) URL=$(URL) $(PY) scripts/e2e.py

load: ## Test de charge en mode fake (sans appel Gemini) et suivi de l'HPA
	@$(MAKE) -s deploy VALUES="--set config.LLM_BACKEND=fake --set config.FAKE_CPU_MS=40"
	@$(PY) scripts/loadtest.py --url $(URL) --concurrency 24 --duration 180 --cooldown 150 --context $(CTX)
	@$(MAKE) -s deploy

status: ## État de la release, des pods et de l'HPA
	@$(H) -n $(NS) history $(RELEASE) 2>/dev/null | tail -5 || true
	@$(K) -n $(NS) get deploy,pods,hpa,pdb -o wide 2>/dev/null || echo "Cluster absent."

down: ## Supprime le cluster kind et vérifie
	@kind delete cluster --name $(CLUSTER)
	@! kind get clusters 2>/dev/null | grep -qx $(CLUSTER) && echo "Cluster $(CLUSTER) supprimé."

clean: ## Supprime le cluster et les artefacts locaux
	@kind get clusters 2>/dev/null | grep -qx $(CLUSTER) && $(MAKE) -s down || true
	@rm -rf .pytest_cache tests/__pycache__ app/__pycache__ scripts/__pycache__
	@docker image rm -f $$(docker images -q $(IMAGE) | sort -u) >/dev/null 2>&1 || true
	@echo "Artefacts supprimés."

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

cloud-up: ## Sans objet : ce projet ne crée rien dans le cloud
	@echo "Ce projet tourne entièrement sur kind. GKE : voir le projet « Kubernetes en production »."
cloud-down: ## Sans objet (rien à supprimer dans le cloud)
	@echo "Aucune ressource cloud. Pour le cluster local : make down"
cloud-status: ## Sans objet (rien dans le cloud)
	@echo "Aucune ressource cloud."
