# Makefile frontend for scikit-build-core project
# Generated by buildgen for: softcut
#
# This Makefile wraps common build commands for convenience.
# The actual build is handled by scikit-build-core via pyproject.toml

.PHONY: all sync build rebuild build-tinyosc build-no-tinyosc build-bench \
		build-standalone test-standalone touchosc test lint format typecheck \
		qa demos demo-looper clean distclean wheel sdist dist check publish-test \
		publish upgrade coverage coverage-html docs docs-serve docs-deploy help

# Default target
all: build

# Sync environment (initial setup, installs dependencies + package)
sync:
	@uv sync

# Build/rebuild the extension after code changes
build:
	@uv sync --reinstall-package softcut-py

# Alias for build
rebuild: build

# Build with the native OSC codec (vendored tinyosc) compiled in. This is the
# default; the target stays for an explicit, cache-busting rebuild.
build-tinyosc:
	@SKBUILD_CMAKE_DEFINE="SOFTCUT_ENABLE_TINYOSC=ON" uv sync --reinstall-package softcut-py --no-cache

# Build *without* tinyosc, to exercise the pure-Python (python-osc) path.
build-no-tinyosc:
	@SKBUILD_CMAKE_DEFINE="SOFTCUT_ENABLE_TINYOSC=OFF" uv sync --reinstall-package softcut-py --no-cache

# Build for benchmarks/osc_jitter.py: native OSC transport plus the compile-time
# apply-latency probe (both off in normal builds).
build-bench:
	@SKBUILD_CMAKE_DEFINE="SOFTCUT_ENABLE_TINYOSC=ON;SOFTCUT_ENABLE_BENCH_PROBE=ON" uv sync --reinstall-package softcut-py --no-cache

# Build the standalone, no-Python OSC server binary (clients/softcut-osc).
build-standalone:
	@cmake -S clients/softcut-osc -B build/softcut-osc -DCMAKE_BUILD_TYPE=Release
	@cmake --build build/softcut-osc

# Headless smoke test for the standalone binary (drives it over UDP, no Python
# in the server).
test-standalone: build-standalone
	@python3 clients/softcut-osc/test_smoke.py

# Regenerate the TouchOSC control surface (clients/touchosc) with py2tosc.
touchosc:
	@uv run python clients/touchosc/build_layout.py

# Run tests
test:
	@uv run pytest tests/ -v

# Lint with ruff
lint:
	@uv run ruff check --fix src/ tests/

# Format with ruff
format:
	@uv run ruff format src/ tests/

# Type check with mypy
typecheck:
	@uv run mypy src/softcut/ tests/ --exclude '.venv'

# Run a full quality assurance check
qa: test lint typecheck format

# Play the offline demos in sequence, live to the speakers (renders to build/out/
# too). Covers every NN_*.py demo except 06, the interactive mic looper.
demos:
	@for d in demos/[0-9][0-9]_*.py; do \
		case $$d in demos/06_*) continue;; esac; \
		echo ">>> $$d"; \
		uv run python $$d --play || exit $$?; \
	done

# Run the interactive realtime microphone looper (needs a mic + speakers)
demo-looper:
	@uv run python demos/06_live_looper.py

# Build wheel
wheel:
	@uv build --wheel

# Build source distribution
sdist:
	@uv build --sdist

# Check distributions with twine
check:
	@uv run twine check dist/*

# Build both wheel and sdist
dist: wheel sdist check

# Publish to TestPyPI
publish-test: check
	@uv run twine upload --repository testpypi dist/*

# Publish to PyPI
publish: check
	@uv run twine upload dist/*

# Upgrade all dependencies
upgrade:
	@uv lock --upgrade
	@uv sync

# Run tests with coverage
coverage:
	@uv run pytest tests/ -v --cov=src/softcut --cov-report=term-missing

# Generate HTML coverage report
coverage-html:
	@uv run pytest tests/ -v --cov=src/softcut --cov-report=html
	@echo "Coverage report: htmlcov/index.html"

# Build documentation (MkDocs Material) into site/
docs:
	@uv run --group docs mkdocs build

# Serve the docs locally with live reload
docs-serve:
	@uv run --group docs mkdocs serve

# Deploy the docs to GitHub Pages (builds and force-pushes the gh-pages branch).
# Requires push access to the repo and Pages enabled to serve from gh-pages.
docs-deploy:
	@uv run --group docs mkdocs gh-deploy --force

# Clean build artifacts. The compiled extension lives in the uv-managed venv
# (rebuilt by `make build`), so cleanup must prune .venv and .git: a bare
# `find . -name "*.so" -delete` would wipe every dependency's .so (numpy, etc.)
# inside .venv and break the environment.
clean:
	@rm -rf build/
	@rm -rf dist/
	@rm -rf *.egg-info/
	@rm -rf src/*.egg-info/
	@rm -rf .pytest_cache/
	@find . \( -path ./.venv -o -path ./.git \) -prune -o -name "*.so" -type f -exec rm -f {} +
	@find . \( -path ./.venv -o -path ./.git \) -prune -o -name "*.pyd" -type f -exec rm -f {} +
	@find . \( -path ./.venv -o -path ./.git \) -prune -o -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null || true

# Clean everything including CMake cache
distclean: clean
	@rm -rf CMakeCache.txt CMakeFiles/

# Show help
help:
	@echo "Available targets:"
	@echo "  all          - Build/rebuild the extension (default)"
	@echo "  sync         - Sync environment (initial setup)"
	@echo "  build        - Rebuild extension after code changes"
	@echo "  rebuild      - Alias for build"
	@echo "  test         - Run tests"
	@echo "  lint         - Lint with ruff"
	@echo "  format       - Format with ruff"
	@echo "  typecheck    - Type check with mypy"
	@echo "  qa           - Run full quality assurance (test, lint, typecheck, format)"
	@echo "  demos        - Play the offline demos in sequence (live to speakers)"
	@echo "  demo-looper  - Run the interactive realtime mic looper (demo 06)"
	@echo "  wheel        - Build wheel distribution"
	@echo "  sdist        - Build source distribution"
	@echo "  dist         - Build both wheel and sdist"
	@echo "  check        - Check distributions with twine"
	@echo "  publish-test - Publish to TestPyPI"
	@echo "  publish      - Publish to PyPI"
	@echo "  upgrade      - Upgrade all dependencies"
	@echo "  coverage     - Run tests with coverage"
	@echo "  coverage-html- Generate HTML coverage report"
	@echo "  docs         - Build the documentation site (MkDocs) into site/"
	@echo "  docs-serve   - Serve the docs locally with live reload"
	@echo "  docs-deploy  - Build and publish the docs to GitHub Pages (gh-pages)"
	@echo "  clean        - Remove build artifacts"
	@echo "  distclean    - Remove all generated files"
	@echo "  help         - Show this help message"
