.PHONY: help install install-cli install-skill install-skill-claude install-skill-codex \
	install-skill-hermes install-skill-kimi install-skill-openclaw install-skill-qwen \
	install-skill-cursor install-skill-opencode install-skill-cline install-skill-kilo \
	uninstall reinstall sync test bump \
	lint format typecheck check hooks build publish clean tag release require-tag

VERSION := $(shell grep -m1 '^version' pyproject.toml | cut -d'"' -f2)

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

install: install-cli install-skill  ## Install the luge CLI globally + the Codex and Claude Code skills

install-cli:  ## Install/upgrade the `luge` command globally (editable)
	uv tool install --editable . --force

install-skill: install-skill-claude install-skill-codex  ## Install the skill for Claude Code and Codex

install-skill-claude:
	luge-cli claude skill install --force

install-skill-codex:
	luge-cli codex skill install --force

# Not part of `install-skill`: writing into ~/.hermes or ~/.kimi-code would
# create a home for an agent that may not be installed on this machine.
install-skill-hermes:  ## Install the skill for Hermes
	luge-cli hermes skill install --force

install-skill-kimi:  ## Install the skill for Kimi Code
	luge-cli kimi skill install --force

install-skill-openclaw:  ## Install the skill for OpenClaw
	luge-cli openclaw skill install --force

install-skill-qwen:  ## Install the skill for Qwen Code
	luge-cli qwen skill install --force

install-skill-cursor:  ## Install the skill for Cursor
	luge-cli cursor skill install --force

install-skill-opencode:  ## Install the skill for opencode
	luge-cli opencode skill install --force

install-skill-cline:  ## Install the skill for Cline
	luge-cli cline skill install --force

install-skill-kilo:  ## Install the skill for Kilo Code
	luge-cli kilo skill install --force

uninstall:  ## Remove the CLI and the skill
	-uv tool uninstall luge-cli
	-rm -rf $(HOME)/.claude/skills/luge-platform
	-rm -rf $(HOME)/.codex/skills/luge-platform
	-rm -rf $(HOME)/.hermes/skills/luge-platform
	-rm -rf $(HOME)/.kimi-code/skills/luge-platform
	-rm -rf $(HOME)/.openclaw/skills/luge-platform
	-rm -rf $(HOME)/.qwen/skills/luge-platform
	-rm -rf $(HOME)/.cursor/skills/luge-platform
	-rm -rf $(HOME)/.config/opencode/skills/luge-platform
	-rm -rf $(HOME)/.cline/skills/luge-platform
	-rm -rf $(HOME)/.kilo/skills/luge-platform $(HOME)/.kilocode/skills/luge-platform

reinstall: uninstall install  ## Clean reinstall

sync:  ## Create/refresh the local dev environment
	uv sync

test:  ## Run the test suite
	uv run pytest -q

lint:  ## Lint with ruff (check only)
	uv run ruff check .

format:  ## Auto-fix lint issues and format with ruff
	uv run ruff check --fix .
	uv run ruff format .

typecheck:  ## Type-check with mypy
	uv run mypy src/luge_cli

check: lint typecheck test  ## Lint + type-check + test (what CI runs)
	uv run ruff format --check .

hooks:  ## Install the pre-commit git hooks
	uv run pre-commit install

clean:  ## Remove build artifacts
	rm -rf dist build ./*.egg-info

build: clean check  ## Build the sdist + wheel (runs checks first)
	uv build

# Refuse to publish a version that isn't tagged: a PyPI upload is permanent, so it
# must correspond to a v<version> git tag on the current, clean commit. Run
# `make release` (or `make tag`) first.
require-tag:
	@git rev-parse -q --verify "refs/tags/v$(VERSION)" >/dev/null || { \
		echo "Refusing to publish v$(VERSION): no git tag v$(VERSION) — run 'make release' first."; \
		exit 1; }
	@test "$$(git rev-parse HEAD)" = "$$(git rev-parse 'v$(VERSION)^{commit}')" || { \
		echo "Refusing to publish v$(VERSION): HEAD is not at tag v$(VERSION)."; exit 1; }
	@test -z "$$(git status --porcelain)" || { \
		echo "Refusing to publish v$(VERSION): the working tree is dirty."; exit 1; }

# Uploads to the repository configured in ~/.pypirc (override: make publish REPO=testpypi).
REPO ?= pypi
publish: require-tag build  ## Build and upload to PyPI (requires a matching git tag)
	uv run twine check dist/*
	uv run twine upload -r $(REPO) dist/*

tag:  ## Tag the current version (vX.Y.Z) and push the tag
	git tag -a v$(VERSION) -m "v$(VERSION)"
	git push origin v$(VERSION)

# The version is the release's business, not a merge's: work accumulates under
# `## [Unreleased]` in CHANGELOG.md, and this closes it under a number at the
# one moment the number is knowable — when someone decides to publish and can
# check it against what PyPI already holds. Bumping per unit of work is how this
# repo once reached 0.50.0 while PyPI held 0.47.0.
bump:  ## Set the release version and close the changelog (make bump V=0.48.0)
	@test -n "$(V)" || { echo "Usage: make bump V=X.Y.Z"; exit 1; }
	uv run python scripts/bump_version.py $(V)
	uv lock

# `install-cli` closes a trap of the editable install: the version comes from
# the package metadata written at install time, not from pyproject.toml, so a
# bumped version leaves `luge-cli --version` reporting the old one until the
# tool is reinstalled. Tagging is the moment that must stop being true.
release: tag install-cli  ## Tag + GitHub release, and realign the local install
	@awk '/^## \[$(VERSION)\]/{f=1;next} /^## \[/{f=0} f' CHANGELOG.md > .release-notes.md
	gh release create v$(VERSION) --title "v$(VERSION)" --notes-file .release-notes.md
	@rm -f .release-notes.md
