.PHONY: lint format format-check typecheck test test-ci test-ci-serial test-ci-forked test-integration imports-check check clean install demo demo-prep demo-publish build publish release release-promote docs docs-api docs-site site site-serve site-tar dns-setup qa-pod-volume qa-pod-up qa-pod-logs qa-pod-down

lint:
	uv run ruff check src/ tests/ tools/qa/ scripts/qa/
	uv run python scripts/check_style_rules.py

format:
	uv run ruff format src/ tests/ tools/qa/ scripts/qa/

format-check:
	uv run ruff format --check src/ tests/ tools/qa/ scripts/qa/

typecheck:
	uv run mypy src/lilbee/

test:
	uv run pytest --cov=lilbee --cov-report=term-missing -v -n logical --dist loadgroup

test-ci:
	uv run pytest --cov=lilbee --cov-report=term-missing --cov-report=html $(COV_FLAGS) -v -n logical --dist loadgroup

test-ci-serial:
	uv run pytest --cov=lilbee --cov-report=term-missing --cov-report=html -v -p no:xdist

test-ci-forked:
	uv run pytest --forked -v -n logical --dist loadgroup

imports-check:
	uv run python -c "import lilbee; from lilbee import cli; from lilbee.core import config; from lilbee.data import chunk, code_chunker, store, ingest; from lilbee.retrieval import embedder, query"

test-integration:
	uv run pytest tests/integration/ -v

check: lint format-check typecheck test  ## Run all checks (same as CI)

install:
	uv tool install ".[crawler]" --force --reinstall --compile-bytecode

crawl-setup:  ## Download Playwright Chromium for /crawl
	uv run playwright install chromium

dns-setup:  ## One-time DNS setup for lilbee.sh at Porkbun (reads creds from pass)
	bash scripts/porkbun-dns-setup.sh

demo-prep:  ## Stage demo data dirs via the gh-pages worktree
	bash scripts/demo.sh prep

demo:  ## Render every demo GIF via the gh-pages worktree
	bash scripts/demo.sh render

demo-publish:  ## Commit + push refreshed renders on gh-pages
	bash scripts/demo.sh publish

build:
	uv build

publish: build  ## Build and upload to PyPI
	uv publish

release:  ## Bump the beta version, tag, and push; CI builds + publishes
	bash scripts/release.sh

release-promote:  ## Rewrite notes as headings and mark a release latest (TAG=... or newest); run after the PyPI publish is green
	@tag="$(TAG)"; \
	[ -n "$$tag" ] || tag=$$(gh release list --repo tobocop2/lilbee --limit 30 --json tagName -q "first(.[].tagName | select(startswith(\"v\")))"); \
	verified=$$(gh run list --repo tobocop2/lilbee --workflow=verify-release.yml --limit 50 --json displayTitle,conclusion -q "[.[] | select(.displayTitle == \"Verify release $$tag\" and .conclusion == \"success\")] | length"); \
	if [ "$$verified" = "0" ]; then \
	  echo "REFUSING to promote $$tag: no green 'Verify release' run for it."; \
	  echo "The verify-release workflow must pass against the release assets first:"; \
	  echo "  gh workflow run verify-release.yml -f tag=$$tag"; \
	  exit 1; \
	fi; \
	prev=$$(gh release list --repo tobocop2/lilbee --exclude-drafts --limit 30 --json tagName -q "first(.[].tagName | select(startswith(\"v\") and . != \"$$tag\"))"); \
	echo "release-promote: $$tag (verified; notes diff from $$prev)"; \
	notes=$$(mktemp); \
	bash scripts/release_notes.sh tobocop2/lilbee "$$tag" "$$prev" > "$$notes"; \
	gh release edit "$$tag" --repo tobocop2/lilbee --notes-file "$$notes" --prerelease=false --latest; \
	rm -f "$$notes"

docs-api:  ## Generate OpenAPI schema and Redoc static HTML
	uv run python -c "\
	from lilbee.server.app import create_app; \
	import json; \
	app = create_app(); \
	schema = app.openapi_schema.to_schema(); \
	open('openapi.json', 'w').write(json.dumps(schema, indent=2))"
	npx --yes @redocly/cli build-docs openapi.json -o site/api/index.html
	rm -f openapi.json

docs-site: docs-api  ## Build the full dev portal (coverage + API docs)
	$(MAKE) test-ci
	cp -r htmlcov site/coverage

docs: docs-site  ## Alias for docs-site

site: docs-api  ## Build the deployable site locally (marketing pages + API docs; no coverage build)
	@echo "site/ is ready. Preview with: make site-serve"

site-serve: site  ## Build + serve the site at http://localhost:8000
	cd site && python3 -m http.server 8000

site-tar: site  ## Build the site and pack it into site.tar.gz
	tar -czf site.tar.gz -C site .
	@echo "wrote site.tar.gz"

# --- opencode QA pod (SkyPilot + RunPod) ------------------------------------
# Provisioning is SkyPilot; it reads the RunPod key from ~/.runpod/config.toml.
# One-time: pip install "skypilot[runpod]" && runpod config && sky check runpod.
# See tools/qa/opencode/README.md.
QA_SKY := tools/qa/opencode

qa-pod-volume:  ## Create/adopt the reusable QA network volume (once)
	sky volumes apply $(QA_SKY)/qa-volume.sky.yaml

qa-pod-up:  ## Provision the QA pod, bootstrap, and run the matrix (MATRIX_ARGS=... to narrow)
	# -i 30 --down: autostop after 30 min idle and tear the pod down when the matrix
	# finishes, so a finished or hung run never bills idle. The volume keeps the
	# engine, models, and results; reels just re-launch (a warm volume boots fast).
	# HF_TOKEN (from your shell) is passed as a --secret so gated pulls work and
	# the token stays redacted in sky logs; unset = ungated models only.
	sky launch -c lilbee-qa $(QA_SKY)/qa-pod.sky.yaml -y -i 30 --down $(if $(HF_TOKEN),--secret HF_TOKEN="$(HF_TOKEN)",) $(if $(MATRIX_ARGS),--env MATRIX_ARGS="$(MATRIX_ARGS)",)

qa-pod-logs:  ## Follow the QA pod's run log
	sky logs lilbee-qa

qa-pod-down:  ## Tear down the QA pod (the volume and its state survive)
	sky down lilbee-qa -y

clean:
	rm -rf .mypy_cache .pytest_cache .ruff_cache htmlcov .coverage dist/ openapi.json site/api site/coverage site.tar.gz
	find . -type d -name __pycache__ -exec rm -rf {} +
