UV := $(or $(shell command -v uv 2>/dev/null),$(HOME)/.local/bin/uv)

# Editor CLI used by `make wt-open` to open each worktree in a new window.
# Override for forks of VS Code (e.g. `CODE=cursor make wt-open NAME=my-feature`).
CODE ?= code

.PHONY: install dev test test-fast test-v test-all lint format security run run-dry clean env pre-commit graph eval contract record smoke-test snapshot-update budget-report bump-patch bump-minor bump-major build publish help wt-new wt-open wt-list wt-rm wt-rm-all

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

install: ## Install uv (if missing) and project dependencies
	@command -v uv >/dev/null 2>&1 || (echo "Installing uv..." && curl -LsSf https://astral.sh/uv/install.sh | sh)
	$(UV) venv
	$(UV) pip install -e ".[dev]"

env: ## Copy .env.example to .env (won't overwrite existing)
	@if [ -f .env ]; then echo ".env already exists — skipping"; else cp .env.example .env && echo "Created .env from .env.example — fill in your keys"; fi

test-fast: ## Unit tests only — < 3s, no graph compilation (tight edit-test loop)
	$(UV) run pytest tests/unit/ --tb=short -q
	@echo "✓ Unit tests passed"

test: ## Unit + integration + contract tests — full suite, no API keys needed
	$(UV) run pytest tests/unit/ tests/integration/ tests/contract/ --tb=short
	@echo "✓ All tests passed"

test-v: ## Unit + integration + contract tests (verbose)
	$(UV) run pytest tests/unit/ tests/integration/ tests/contract/ -v

test-all: ## Everything including golden evaluators (requires make eval separately for golden)
	$(UV) run pytest --ignore=tests/smoke --tb=short
	@echo "✓ Full test suite passed"

lint: ## Lint with ruff
	$(UV) run ruff check src/ tests/

format: ## Format with ruff
	$(UV) run ruff format src/ tests/

security: ## Security scan — bandit (ruff S) SAST + dependency CVE audit
	@echo "→ SAST (ruff incl. flake8-bandit S rules; respects pyproject ignores)"
	$(UV) run ruff check src/ tests/
	@echo "→ Dependency CVE audit (pip-audit against the synced environment)"
	$(UV) run --with pip-audit pip-audit
	@echo "✓ Security scan passed"

pre-commit: ## Install pre-commit hooks
	$(UV) run pre-commit install

run: ## Run the yeaboi CLI (use ARGS="--flag" to pass arguments)
	$(UV) run yeaboi $(ARGS)

run-dry: ## Run the TUI with fake delays — no LLM calls
	$(UV) run yeaboi --dry-run $(ARGS)

eval: ## Run golden dataset evaluators
	$(UV) run pytest tests/golden/ -v

contract: ## Run contract tests (recorded API responses + LLM provider parsing)
	$(UV) run pytest tests/contract/ -v

smoke-test: ## Run smoke tests against live APIs (requires real credentials)
	$(UV) run pytest tests/smoke/ -v -m smoke

record: ## Re-record VCR cassettes against real APIs (requires API keys)
	$(UV) run pytest tests/ -v --record-mode=rewrite -m vcr

snapshot-update: ## Update syrupy snapshot baselines after intentional formatter changes
	$(UV) run pytest tests/unit/test_formatters.py --snapshot-update -v

budget-report: ## Show live prompt token counts for trend monitoring (runs token budget tests with -s)
	$(UV) run pytest tests/unit/test_token_budgets.py -v -s

graph: ## Generate agent graph visualisation PNG
	$(UV) run python scripts/generate_graph_png.py

bump-patch: ## Bump the patch version in pyproject.toml (X.Y.Z -> X.Y.Z+1)
	$(UV) run python scripts/bump_version.py patch

bump-minor: ## Bump the minor version in pyproject.toml (X.Y.Z -> X.Y+1.0)
	$(UV) run python scripts/bump_version.py minor

bump-major: ## Bump the major version in pyproject.toml (X.Y.Z -> X+1.0.0)
	$(UV) run python scripts/bump_version.py major

build: ## Build sdist + wheel into dist/
	$(UV) build

publish: ## Publish to PyPI (use GitHub Actions for production releases)
	$(UV) publish

# --- Worktrees — parallel Claude sessions, one per task (NAME= required) ------

# Guard NAME= for every wt-* target without duplicating the message.
define need-name
	@test -n "$(NAME)" || { echo "usage: make $@ NAME=<slug>  (e.g. NAME=standup-fix)"; exit 1; }
endef

wt-new: ## Create worktree .claude/worktrees/NAME (branch + .env + venv) + open in VS Code with claude auto-running
	$(need-name)
	CODE="$(CODE)" bash scripts/wt.sh "$(NAME)" open

wt-open: ## Open worktree in a NEW VS Code window with claude auto-running (creates it first if needed)
	$(need-name)
	CODE="$(CODE)" bash scripts/wt.sh "$(NAME)" open

wt-list: ## List worktrees (branch, clean/dirty, path)
	@bash scripts/wt-list.sh

wt-rm: ## Remove worktree dir + branch
	$(need-name)
	bash scripts/wt.sh "$(NAME)" rm

wt-rm-all: ## Remove ALL worktrees under .claude/worktrees/ (prompts to confirm)
	@read -r -p "Remove ALL .claude/worktrees/* worktrees and their branches? [y/N] " ans; \
	  if [ "$$ans" = "y" ] || [ "$$ans" = "Y" ]; then \
	    for w in $$(git worktree list --porcelain | awk '/^worktree /{print $$2}' | grep "/.claude/worktrees/" || true); do \
	      name="$$(basename "$$w")"; echo "[wt-rm-all] removing $$name"; bash scripts/wt.sh "$$name" rm || true; \
	    done; \
	    git worktree prune; echo "[wt-rm-all] done."; \
	  else echo "[wt-rm-all] aborted"; fi

clean: ## Remove build artifacts and caches
	rm -rf .venv build dist .pytest_cache .ruff_cache *.egg-info src/*.egg-info
	find . -type d -name __pycache__ -exec rm -rf {} +
