# HyperMind — developer Makefile
#
# Usage:
#   make help            Show available targets (default)
#   make bootstrap       Create .venv and install editable with [test,dev] extras
#   make fmt / lint      Format / lint via ruff
#   make typecheck       Run mypy (allow-error during alpha; strict gate at v0.6)
#   make test / cov      Run pytest, optionally with 95% coverage gate
#   make demo / demos    Run example(s)
#   make check           Composite: lint + typecheck + cov
#   make clean           Remove caches and build artifacts
#
# Conventions:
#   - All Python invocations go through .venv/bin/python (project's documented
#     pattern in CONTRIBUTING.md).
#   - Run `make bootstrap` once before anything else.

PY      := .venv/bin/python
PIP     := .venv/bin/pip
RUFF    := .venv/bin/ruff
MYPY    := .venv/bin/mypy
PYTEST  := .venv/bin/pytest

SRC_DIRS := src tests examples
COV_PKGS := --cov=src/hypermind --cov=src/hmctl

.DEFAULT_GOAL := help

.PHONY: help bootstrap fmt lint typecheck test cov cov-html demo demos check clean docs-serve release-build sbom lockfiles audit run run-fast webui-build webui-dev

help:  ## Print available targets
	@echo "HyperMind — make targets"
	@echo ""
	@echo "  bootstrap     Create venv + install editable with [test,dev] extras"
	@echo "  fmt           ruff format src tests examples"
	@echo "  lint          ruff check + ruff format --check"
	@echo "  typecheck     mypy src/hypermind src/hmctl (allow-error during alpha)"
	@echo "  test          pytest -q"
	@echo "  cov           pytest with coverage gate (--cov-fail-under=95)"
	@echo "  cov-html      pytest with HTML coverage report (htmlcov/)"
	@echo "  demo          Run examples/01_hello_world"
	@echo "  demos         Run all numbered tutorials + scenarios sequentially (with timeout)"
	@echo "  check         Composite gate: lint + typecheck + cov"
	@echo "  clean         Remove caches and build artifacts"
	@echo "  docs-serve    [placeholder] MkDocs site lands v1.0"
	@echo "  release-build python -m build && twine check dist/*"
	@echo "  run           Build webui + start SimLab UI on http://127.0.0.1:8765"
	@echo "  run-fast      Start SimLab UI without rebuilding the webui"
	@echo "  webui-build   Build the Vue/Vite webui only"
	@echo "  webui-dev     Vite dev server with hot-reload on :5173"

bootstrap:  ## Create venv + install editable with [test,dev] extras
	python3.13 -m venv .venv
	$(PY) -m pip install --upgrade pip
	$(PIP) install -e ".[test,dev]"

fmt:  ## ruff format
	$(RUFF) format $(SRC_DIRS)

lint:  ## ruff check + format --check
	$(RUFF) check $(SRC_DIRS)
	$(RUFF) format --check $(SRC_DIRS)

typecheck:  ## mypy (allow-error during alpha; strict gate at v0.6)
	-$(MYPY) src/hypermind src/hmctl

test:  ## pytest -q
	$(PYTEST) -q

cov:  ## pytest with --cov-fail-under=95
	$(PYTEST) $(COV_PKGS) --cov-fail-under=95

cov-html:  ## pytest with HTML coverage report
	$(PYTEST) $(COV_PKGS) --cov-report=html
	@echo "Open htmlcov/index.html"

demo:  ## Run examples/01_hello_world
	$(PY) -m examples.01_hello_world

demos:  ## Run every example end-to-end (60s timeout each)
	@for ex in \
		01_hello_world 02_two_agents_dispute 03_consult_panel 04_oracle_resolve \
		05_consult_to_synthesis 08_ramp_and_diagnostics 09_audit_export_chain \
		scenario_threat_intel scenario_namespace_trust scenario_information_pipeline \
		scenario_vouch_chain scenario_learning_loop scenario_cross_namespace_federation \
		scenario_capability_attenuation scenario_dispute_lifecycle_async \
		lifecycle full_e2e_demo; do \
		echo "=== Running examples.$$ex ==="; \
		timeout 60 $(PY) -m examples.$$ex >/dev/null || { echo "FAILED: $$ex"; exit 1; }; \
	done
	@echo "✓ all examples ran end-to-end"

check: lint typecheck cov  ## Composite: lint + typecheck + cov

clean:  ## Remove caches and build artifacts
	rm -rf .pytest_cache .mypy_cache .ruff_cache htmlcov dist build *.egg-info

docs-serve:  ## [placeholder] MkDocs site lands v1.0
	@echo "MkDocs site lands v1.0 — see docs/ for source material."

run: webui-build  ## Build webui + start SimLab UI on http://127.0.0.1:8765
	@echo ""
	@echo "  HyperMind SimLab — http://127.0.0.1:8765"
	@echo "  Routes: /  /how-it-works  /evidence  /security  /usecases  /paper  /docs  /sims"
	@echo ""
	$(PY) -m hmctl simlab

run-fast:  ## Start SimLab UI without rebuilding the webui (use when JS unchanged)
	$(PY) -m hmctl simlab

webui-build:  ## Build the Vue/Vite webui into src/hypermind/simlab/ui/dist
	@if [ ! -d webui/node_modules ]; then \
		echo "Installing webui dependencies..."; \
		cd webui && npm install; \
	fi
	cd webui && npm run build

webui-dev:  ## Run vite dev server with HMR on http://127.0.0.1:5173 (requires `make run-fast` separately for the API)
	@if [ ! -d webui/node_modules ]; then cd webui && npm install; fi
	cd webui && npm run dev

release-build:  ## python -m build + twine check
	$(PY) -m build
	$(PY) -m twine check dist/*

# WS-A supply-chain hardening (v0.6) targets ---------------------------------

sbom:  ## Generate CycloneDX SBOM (sbom.cdx.json) from current venv
	.venv/bin/cyclonedx-py environment -o sbom.cdx.json
	@echo "Wrote sbom.cdx.json"

lockfiles:  ## Regenerate hash-pinned requirements.lock + requirements-dev.lock
	.venv/bin/pip-compile --generate-hashes --quiet \
	    --output-file=requirements.lock pyproject.toml
	.venv/bin/pip-compile --generate-hashes --quiet \
	    --extra=test --extra=dev \
	    --output-file=requirements-dev.lock pyproject.toml

audit:  ## Run pip-audit against committed lockfiles
	.venv/bin/pip-audit --strict --requirement requirements.lock
	.venv/bin/pip-audit --strict --requirement requirements-dev.lock
