SHELL := /bin/bash
.SHELLFLAGS := -eu -o pipefail -c
PY ?= .venv/bin/python
SLUG := plateforme-ia-modulaire
# Pas de `-include .env` + `export` : la ligne de commande doit toujours l'emporter.
# On lit dans .env les deux seules valeurs utiles, sans exporter le reste.
PROJECT ?= $(shell sed -n 's/^GOOGLE_CLOUD_PROJECT=//p' .env 2>/dev/null)
TICKETING_TOKEN ?= $(shell sed -n 's/^TICKETING_TOKEN=//p' .env 2>/dev/null)
REGION ?= europe-west1
BOOT := infra/bootstrap
DEV := infra/envs/dev
PROD := infra/envs/prod
# Terraform lit ses variables dans TF_VAR_* : seules celles-ci sont exportées.
export TF_VAR_project_id = $(PROJECT)
export TF_VAR_ticketing_token = $(TICKETING_TOKEN)
STATE_BUCKET = $$(terraform -chdir=$(BOOT) output -raw state_bucket)
PROD_IMAGE := europe-west1-docker.pkg.dev/logi-ia-prod/lab-pia-prod-images/triage@sha256:$(shell printf "0%.0s" {1..64})
TAG := $(shell date +%Y%m%d-%H%M%S)

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

setup: ## Crée .venv, installe les dépendances, vérifie Terraform
	@test -d .venv || python3 -m venv .venv
	@.venv/bin/pip install -q -r requirements.txt
	@test -f .env || cp .env.example .env
	@terraform version | sed -n 1p
	@echo "Prêt. Renseignez .env puis : make test"

test: ## Tests sans clé ni cloud : pytest, terraform fmt et validate
	@$(PY) -m pytest -q tests
	@terraform fmt -check -recursive infra && echo "fmt : OK"
	@# Dossier de travail séparé : valider sans toucher au backend réel (ni au bucket d'état).
	@for d in $(BOOT) $(DEV) $(PROD); do \
	  export TF_DATA_DIR=.terraform-ci; \
	  terraform -chdir=$$d init -backend=false -input=false >/dev/null && \
	  terraform -chdir=$$d validate -no-color | grep -v "^$$" | sed "s|^|$$d : |"; done

run: ## Lance le service en local (identifiants ADC, Vertex AI)
	@cd app && GOOGLE_CLOUD_PROJECT=$(PROJECT) GOOGLE_CLOUD_LOCATION=$(REGION) ../$(PY) -m uvicorn main:app --port 8080

state-up: ## Crée le bucket d'état (versionné, verrouillé)
	@terraform -chdir=$(BOOT) init -input=false >/dev/null
	@terraform -chdir=$(BOOT) apply -input=false -auto-approve -no-color | tail -3

init: ## Branche infra/envs/dev sur le bucket d'état
	@terraform -chdir=$(DEV) init -input=false -reconfigure -backend-config=bucket=$(STATE_BUCKET) -no-color | grep -E "backend|Terraform has been"

plan: init ## Plan de dev (lecture seule)
	@terraform -chdir=$(DEV) plan -input=false -no-color

plan-prod: ## Plan de prod (projet fictif, lecture seule, état dans le même bucket)
	@terraform -chdir=$(PROD) init -input=false -reconfigure -backend-config=bucket=$(STATE_BUCKET) >/dev/null
	@terraform -chdir=$(PROD) plan -input=false -no-color -var image=$(PROD_IMAGE)

cloud-up: state-up init ## Crée dev : socle, image, puis service
	@terraform -chdir=$(DEV) apply -input=false -auto-approve -no-color | tail -1
	@$(MAKE) --no-print-directory image TAG=$(TAG)
	@terraform -chdir=$(DEV) apply -input=false -auto-approve -no-color \
	  -var image=$$(cat .image) -var app_version=$(TAG) | tail -4

image: ## Construit et pousse l'image (épinglée par digest)
	@repo=$$(terraform -chdir=$(DEV) output -raw registry_url); \
	docker build -q -t $$repo/triage:$(TAG) app >/dev/null; \
	cfg=$$(mktemp -d); trap 'rm -rf $$cfg' EXIT; \
	gcloud auth print-access-token | DOCKER_CONFIG=$$cfg docker login -u oauth2accesstoken --password-stdin https://$(REGION)-docker.pkg.dev >/dev/null 2>&1; \
	DOCKER_CONFIG=$$cfg docker push -q $$repo/triage:$(TAG) >/dev/null; \
	docker inspect --format '{{index .RepoDigests 0}}' $$repo/triage:$(TAG) > .image; \
	echo "image : $$(sed 's|$(PROJECT)|<projet>|' .image)"

e2e: ## Appelle le service déployé (identité gcloud)
	@$(PY) e2e.py "$$(terraform -chdir=$(DEV) output -raw service_uri)"

cloud-status: ## Ressources du lab encore présentes (code 1 s'il en reste)
	@n=0; p=lab-pia; \
	chk() { out=$$("$${@:2}" 2>/dev/null || true); if [ -n "$$out" ]; then echo "RESTE $$1 : $$out"; n=$$((n+1)); fi; }; \
	chk "Cloud Run" gcloud run services list --project $(PROJECT) --region $(REGION) --filter="metadata.name~^$$p" --format="value(metadata.name)"; \
	chk "Artifact Registry" gcloud artifacts repositories list --project $(PROJECT) --location $(REGION) --filter="name~/$$p" --format="value(name)"; \
	chk "Secrets" gcloud secrets list --project $(PROJECT) --filter="labels.formation-lab=$(SLUG)" --format="value(name)"; \
	chk "Buckets" gcloud storage buckets list --project $(PROJECT) --filter="labels.formation-lab=$(SLUG)" --format="value(name)"; \
	chk "Comptes de service" gcloud iam service-accounts list --project $(PROJECT) --filter="email~^$$p" --format="value(email)"; \
	chk "Sinks" gcloud logging sinks list --project $(PROJECT) --filter="name~^$$p" --format="value(name)"; \
	chk "Métriques" gcloud logging metrics list --project $(PROJECT) --filter="name~^$$p" --format="value(name)"; \
	chk "IAM projet" gcloud projects get-iam-policy $(PROJECT) --flatten="bindings[].members" --filter="bindings.members~$$p" --format="value(bindings.role)"; \
	if [ $$n -eq 0 ]; then echo "Aucune ressource $(SLUG) restante."; else exit 1; fi

cloud-down: ## Détruit dev puis le bucket d'état, et vérifie
	@if terraform -chdir=$(BOOT) output -raw state_bucket >/dev/null 2>&1; then \
	  $(MAKE) --no-print-directory init >/dev/null; \
	  terraform -chdir=$(DEV) destroy -input=false -auto-approve -no-color | tail -1; \
	  terraform -chdir=$(BOOT) destroy -input=false -auto-approve -no-color | tail -1; \
	fi
	@rm -f .image
	@# Les listes IAM sont à cohérence différée : un compte supprimé peut y figurer encore
	@# quelques secondes. On revérifie avant de conclure qu'il reste quelque chose.
	@for i in 1 2 3; do $(MAKE) --no-print-directory cloud-status && exit 0; sleep 15; done; exit 1

clean: ## Supprime les artefacts locaux (caches, plans, .terraform)
	@rm -rf .pytest_cache tests/__pycache__ app/__pycache__ .image *.tfplan .terraform-ci
	@find infra \( -name .terraform -o -name .terraform-ci \) -type d -prune -exec rm -rf {} +
	@docker images -q '*/*/lab-pia-*/triage' | sort -u | xargs -r docker rmi -f >/dev/null
	@echo "Artefacts supprimés (l'état local de infra/bootstrap est conservé)."

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

down: ## Sans objet : pas de pile Docker locale
	@echo "Pas de pile locale. Pour le cloud : make cloud-down"
