# sengol — developer entry points.
#
# `make demo` is the answer to "I installed it and the Console is empty"
# (issue #442): it brings the stack up and seeds it with a realistic fleet.

COMPOSE ?= docker compose
API_URL ?= http://localhost:8080
TENANT  ?= dev-tenant

# docker-compose.yml sets SENGOL_JWT_SIGNING_KEY, so `require_scope()` validates
# every bearer credential as an HS256 JWT — a literal `dev` token 401s on the
# first request and the "zero-configuration demo" would seed nothing (Codex
# review, PR #454). The seeder exchanges this bootstrap secret for a
# console_admin JWT instead. Must match SENGOL_CONSOLE_ADMIN_SECRET_dev_tenant
# in docker-compose.yml.
# NOT a `?=` default: `make seed API_URL=... TOKEN=...` against a REMOTE
# deployment must use the token the caller supplied, and an always-set default
# here made the seeder ignore it and attempt the compose-only bootstrap
# exchange instead (Codex review, PR #454). `demo` sets it explicitly below;
# standalone callers opt in with `make seed ADMIN_SECRET=...`.
ADMIN_SECRET ?=
COMPOSE_ADMIN_SECRET ?= dev-admin-bootstrap-secret
# Used when ADMIN_SECRET is empty — an auth-disabled deployment, or a caller
# passing their own bearer token.
TOKEN   ?= dev

.PHONY: help demo seed demo-down test lint

help:
	@echo "make demo       — bring up compose, seed a demo fleet, print the Console URL"
	@echo "make seed       — seed an ALREADY-running deployment (API_URL=... TOKEN=...)"
	@echo "                  add ADMIN_SECRET=... to bootstrap a JWT instead of using TOKEN"
	@echo "make demo-down  — tear the compose stack down"
	@echo "make test       — pytest (CI marker expression)"
	@echo "make lint       — ruff check + format --check"

# Postgres first, then migrations, then the API. A fresh compose volume is an
# EMPTY database and the image's CMD is uvicorn alone — nothing creates the
# Alembic-managed tables, so a plain `up -d` either crash-loops the API or
# reaches health with no `agent_registrations` for the seeder to write to
# (Codex review, PR #454). Migrations run inside the API image (alembic ships
# in the `server` extra), so no local DSN or Python toolchain is needed.
demo:
	$(COMPOSE) up -d postgres
	@echo "Waiting for Postgres…"
	@for i in $$(seq 1 60); do \
		$(COMPOSE) exec -T postgres pg_isready -q >/dev/null 2>&1 && break; \
		sleep 2; \
	done
	@echo "Running migrations…"
	$(COMPOSE) run --rm --entrypoint alembic sengol-api upgrade head
	$(COMPOSE) up -d
	@echo "Waiting for the API to become ready…"
	@for i in $$(seq 1 60); do \
		curl -sf $(API_URL)/health >/dev/null 2>&1 && break; \
		sleep 2; \
	done
	@curl -sf $(API_URL)/health >/dev/null 2>&1 || { \
		echo "API did not become ready at $(API_URL) — check '$(COMPOSE) logs sengol-api'"; \
		exit 1; \
	}
	@$(MAKE) --no-print-directory seed ADMIN_SECRET=$(COMPOSE_ADMIN_SECRET)

seed:
	@uv run python scripts/seed_demo.py \
		--api-url $(API_URL) --token $(TOKEN) --tenant $(TENANT) \
		$(if $(ADMIN_SECRET),--admin-secret $(ADMIN_SECRET),)

demo-down:
	$(COMPOSE) down -v

test:
	uv run pytest -q -m "not redteam and not postgres and not loadtest" --timeout=120

lint:
	uv run ruff check sengol tests
	uv run ruff format --check sengol tests
