# Makefile frontend for scikit-build-core project
# Generated by buildgen for: cycsound
#
# 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 test test-cli vendor clean distclean wheel sdist dist-ci check publish publish-test help

# Vendored Csound 7 runtime (downloaded on demand by scripts/vendor_csound7.py):
# a CsoundLib64 framework on macOS, a shared library on Linux. On Windows it
# is a system install in C:/Program Files/Csound7_x64 (a path make cannot
# hold as a target), tracked by vendor/.tag alone.
ifeq ($(OS),Windows_NT)
VENDOR_FRAMEWORK := vendor/.tag
else ifeq ($(shell uname),Darwin)
VENDOR_FRAMEWORK := vendor/CsoundLib64.framework
else
VENDOR_FRAMEWORK := vendor/lib/libcsound64.so
endif

# Default target
all: build

# Download/vendor the Csound 7 runtime if it is missing or its vendor/.tag
# differs from the script's default TAG. This is an order-only prerequisite
# of the build/test targets, so it runs before anything that needs it.
VENDOR_TAG := $(subst ",,$(word 3,$(shell grep "^TAG = " scripts/vendor_csound7.py)))
ifneq ($(shell cat vendor/.tag 2>/dev/null),$(VENDOR_TAG))
.PHONY: $(VENDOR_FRAMEWORK)
endif
# On Windows the stamp cannot see Csound 7 being uninstalled; check the DLL.
ifeq ($(OS),Windows_NT)
CSOUND_ROOT ?= C:/Program Files/Csound7_x64
ifneq ($(shell test -f "$(CSOUND_ROOT)/bin/csound7_64.dll" && echo ok),ok)
.PHONY: $(VENDOR_FRAMEWORK)
endif
endif

$(VENDOR_FRAMEWORK):
	@uv run --no-project python scripts/vendor_csound7.py

vendor: $(VENDOR_FRAMEWORK)

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

# Build/rebuild the extension after code changes
build: | $(VENDOR_FRAMEWORK)
	@uv sync --reinstall-package cycsound

# Alias for build
rebuild: build

# Run tests
test: | $(VENDOR_FRAMEWORK)
	@uv run python -m pytest tests/ -v

# Run CLI tests only
test-cli: | $(VENDOR_FRAMEWORK)
	@uv run python -m pytest tests/test_cli.py -v

# Build a wheel for local use. On Windows it is repaired with delvewheel,
# which bundles csound7_64.dll, so it runs without Csound 7 installed.
# Elsewhere it is not repaired (delocate/auditwheel), so it links the vendored
# runtime by absolute path. Release wheels come from CI; see dist-ci.
ifeq ($(OS),Windows_NT)
wheel: | $(VENDOR_FRAMEWORK)
	@rm -rf build/wheel-raw
	@uv build --wheel -o build/wheel-raw -C cmake.define.CYCSOUND_DLLDIR=OFF
	@uvx delvewheel repair --add-path "$(CSOUND_ROOT)/bin" -w dist build/wheel-raw/*.whl
else
wheel:
	@uv build --wheel
endif

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

# Check distribution files with twine
check:
	@uv run python -m twine check dist/*

# Replace dist/ with the wheels and sdist of a CI run, then check them.
# RUN defaults to the latest successful wheels.yml run on the current branch,
# which may predate HEAD; the run's commit is printed.
dist-ci:
	@run="$(RUN)"; \
	run="$${run:-$$(gh run list --workflow wheels.yml --branch "$$(git branch --show-current)" \
		--status success -L 1 --json databaseId -q '.[0].databaseId')}"; \
	test -n "$$run" || { echo "error: no successful wheels.yml run; set RUN=<run-id>" >&2; exit 1; }; \
	gh run view "$$run" --json headSha,displayTitle -q '"run '"$$run"': \(.headSha[:7]) \(.displayTitle)"' && \
	rm -rf dist && gh run download "$$run" -n cycsound-dist -D dist && ls dist
	@uv run python -m twine check dist/*

# Publish to PyPI
publish:
	@uv run python -m twine upload dist/*

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

# Clean build artifacts
clean:
	@rm -rf build/
	@rm -rf dist/
	@rm -rf *.egg-info/
	@rm -rf src/*.egg-info/
	@rm -rf .pytest_cache/
	@find . -name "*.so" -delete
	@find . -name "*.pyd" -delete
	@find . -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 all tests"
	@echo "  test-cli     - Run CLI tests only"
	@echo "  wheel        - Build a wheel for local use (not portable)"
	@echo "  sdist        - Build source distribution"
	@echo "  dist-ci      - Download a CI run's wheels and sdist to dist/ (RUN=<id>)"
	@echo "  check        - Check distribution files with twine"
	@echo "  publish      - Publish to PyPI"
	@echo "  publish-test - Publish to TestPyPI"
	@echo "  clean        - Remove build artifacts"
	@echo "  distclean    - Remove all generated files"
	@echo "  help         - Show this help message"
