COMPOSE_DEV := docker compose -f docker-compose.dev.yml

.DEFAULT_GOAL := help

.PHONY: help dev dev-backend dev-frontend down migrate seed types lint eval e2e

help: ## list available targets
	@grep -E '^[a-zA-Z_-]+:.*## ' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*## "}; {printf "  %-10s %s\n", $$1, $$2}'

dev: ## full dev stack with hot reload (postgres in docker, backend + frontend native)
	@for port in 8000 5173; do \
	  if ss -ltn "sport = :$$port" 2>/dev/null | tail -n +2 | grep -q .; then \
	    echo "ERROR: port $$port is already in use — stale 'uvicorn app.main:app' or 'vite dev'?"; \
	    ss -ltnp "sport = :$$port" 2>/dev/null | tail -n +2; \
	    echo "Kill the shown process and retry."; \
	    exit 1; \
	  fi; \
	done
	$(COMPOSE_DEV) up -d --wait
	$(MAKE) -j2 dev-backend dev-frontend

dev-backend:
	cd backend && uv run uvicorn app.main:app --reload --port 8000

dev-frontend:
	cd frontend && npm run dev

down: ## stop the dev stack
	$(COMPOSE_DEV) down

migrate: ## apply alembic migrations
	cd backend && uv run alembic upgrade head

seed: ## seed dev data
	cd backend && uv run python -m app.seed

types: ## regenerate frontend/src/lib/api/schema.d.ts from the FastAPI OpenAPI schema
	cd backend && uv run python -c "import json, sys; from app.main import app; json.dump(app.openapi(), sys.stdout)" > ../frontend/openapi.json
	cd frontend && npx openapi-typescript openapi.json -o src/lib/api/schema.d.ts
	rm frontend/openapi.json

lint: ## ruff + prettier + eslint + design-token contrast check (CI runs the same)
	cd backend && uv run ruff check . && uv run ruff format --check .
	@# Recompiling Paraglide rewrites every module under src/lib/paraglide/. A
	@# running `make dev` is watching exactly those files and ends up serving a
	@# stale graph (500s until vite restarts) -- and it compiles them through
	@# its own plugin anyway, so skipping is not a gap.
	@if ss -ltn 'sport = :5173' 2>/dev/null | tail -n +2 | grep -q .; then \
	  echo "dev server on :5173 -- keeping its compiled messages, checking files only"; \
	  cd frontend && npm run lint:files; \
	else \
	  cd frontend && npm run lint; \
	fi
	python3 frontend/scripts/contrast-check.py
	python3 frontend/scripts/check-messages.py
	python3 backend/scripts/check-no-ui-strings.py

eval: ## LLM eval suite against the configured endpoints
	cd backend && uv run pytest tests/evals -m eval -s

e2e: ## playwright end-to-end tests against the dev stack
	cd frontend && npm run test:e2e
