# Thin wrappers around uv — same commands as CI and the README.
# On a Pi: `make setup && $EDITOR .env && make serve`
# For dev:  `make setup-dev && make check`

.DEFAULT_GOAL := help

UV      ?= uv
PYTHON  ?= 3.13
SOURCES := server reviewer tests juan cli.py
HOST    ?= 127.0.0.1
PORT    ?= 8000
BASE_URL := http://$(HOST):$(PORT)

.PHONY: help setup setup-dev install-hooks env serve serve-dev docker-build docker-up docker-down \
	docker-logs build install-local smoke-cli fmt lint typecheck test check pre-commit clean live ready health \
	release-dry-run

help: ## Show this help
	@printf "Targets (UV=%s, PYTHON=%s):\n\n" "$(UV)" "$(PYTHON)"
	@grep -E '^[a-zA-Z0-9_.-]+:.*##' $(MAKEFILE_LIST) | \
		awk 'BEGIN {FS = ":.*## "}; {printf "  \033[36m%-16s\033[0m %s\n", $$1, $$2}'

# --- Setup (Pi or laptop) -------------------------------------------------------

setup: ## Install runtime deps; create .env from example if missing
	$(UV) python install $(PYTHON)
	$(UV) sync
	@test -f .env || (cp .env.example .env && printf '\nCreated .env from .env.example — edit it before serving.\n')

setup-dev: setup install-hooks ## Install dev deps and git hooks (pre-commit + pre-push check)

install-hooks: ## Install pre-commit + pre-push hook (runs `make check` before every push)
	$(UV) sync --all-groups
	$(UV) run pre-commit install
	$(UV) run pre-commit install --hook-type pre-push
	@printf '\nHooks installed. git push will run: make check\n'
	@printf 'Bypass in an emergency only: git push --no-verify\n\n'

env: ## Copy .env.example to .env (does not overwrite)
	@test -f .env && printf '.env already exists; not overwriting.\n' || cp .env.example .env

# --- Run ------------------------------------------------------------------------

serve: ## Run the API server (honours SERVER_HOST / SERVER_PORT in .env)
	$(UV) run juan serve

serve-dev: ## Run the server with auto-reload (development only)
	$(UV) run juan serve --reload

# --- Packaging (Phase 1) --------------------------------------------------------

build: ## Build wheel and sdist (uv build)
	$(UV) build

install-local: ## Editable install (uv sync) with juan on PATH
	$(UV) sync --all-groups

smoke-cli: build ## Install wheel in a temp venv; run juan --help
	bash scripts/smoke_install.sh

# Reproduces what .github/workflows/release.yml does locally — minus the
# actual PyPI publish + GitHub Release. Use this before tagging to catch
# packaging or version-mismatch issues without burning a TestPyPI rehearsal.
# Usage: TAG=v0.3.0 make release-dry-run
release-dry-run: ## Local rehearsal of the release workflow (TAG=vX.Y.Z required)
	@if [ -z "$(TAG)" ]; then \
		echo "error: set TAG=vX.Y.Z (got empty TAG)"; exit 1; \
	fi
	$(UV) run python scripts/check_tag_version.py "$(TAG)"
	$(MAKE) check
	rm -f dist/*.whl dist/*.tar.gz
	$(UV) build
	bash scripts/smoke_install.sh
	@echo "release-dry-run: OK ($(TAG)). Tag with: git tag $(TAG) && git push --tags"

# --- Docker ---------------------------------------------------------------------

docker-build: ## Build the local Docker image
	docker compose build

docker-up: ## Start the stack in the background
	docker compose up -d

docker-down: ## Stop the stack
	docker compose down

docker-logs: ## Follow container logs
	docker compose logs -f juan

# --- Quality (matches .github/workflows/ci.yml) ---------------------------------

fmt: ## Auto-format with ruff
	$(UV) run ruff format $(SOURCES)

lint: ## Ruff lint
	$(UV) run ruff check $(SOURCES)

typecheck: ## mypy on server/ and reviewer/
	$(UV) run mypy server reviewer

test: ## Run pytest
	$(UV) run pytest -q

# CI runs without a TTY so rich.console wraps at 80 cols. Pin COLUMNS=80 in
# `check` so wrap-sensitive assertions land the same way locally as in CI.
check: lint ## Lint, format check, typecheck, and test (CI parity)
	$(UV) run ruff format --check $(SOURCES)
	$(UV) run mypy server reviewer
	COLUMNS=80 $(UV) run pytest -q

pre-commit: ## Run all pre-commit hooks on the whole tree
	$(UV) run pre-commit run --all-files

# --- Ops / smoke ----------------------------------------------------------------

live: ## GET /live
	@curl -fsS "$(BASE_URL)/live" ; echo

ready: ## GET /ready (may be 503 if upstreams are down)
	@curl -sS "$(BASE_URL)/ready" | python3 -m json.tool

health: live ready ## Hit /live and /ready

# --- Cleanup --------------------------------------------------------------------

clean: ## Remove local caches and test artifacts
	rm -rf .pytest_cache .mypy_cache .ruff_cache htmlcov .coverage
	find . -type d -name __pycache__ -prune -exec rm -rf {} +
