OCCT_VER ?= 8.0.1
IMG_N    ?= 1
IMAGE    ?= git.stroblme.de/n3xd/occt-build:$(OCCT_VER)-$(IMG_N)
# Build cache lives off the root filesystem, which is tight on this host.
CACHE    ?= /mnt/cache/n3xd/ocp
REPO     := $(shell pwd)
PUBLISH_URL ?= https://git.stroblme.de/api/packages/N3XD/pypi

# The builder image is a compiler appliance: mounted into, never built FROM, so
# iterating on the binding never re-layers the kernel.  $(CACHE) keeps the
# CMake tree and ccache between runs, which is what makes the inner loop a
# recompile of one TU rather than a full build.
DOCKER_RUN = docker run --rm -u $(shell id -u):$(shell id -g) \
	-v $(REPO):/io -v $(CACHE):/cache -e CACHE_ROOT=/cache $(IMAGE)

.PHONY: help image image-push wheel dev shell test test-asan stubs publish clean clean-cache version parity

help:
	@grep -E '^[a-z-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN{FS=":.*?## "}{printf "  %-14s %s\n", $$1, $$2}'

image: ## Build the OCCT builder image (~40 min; only when occt/Dockerfile changes)
	docker build -f occt/Dockerfile -t $(IMAGE) occt/

image-push: ## Push the builder image (needs: docker login git.stroblme.de)
	docker push $(IMAGE)

wheel: ## Build + repair + smoke-test the wheel into wheelhouse/
	$(DOCKER_RUN) bash /io/scripts/build_wheel.sh

dev: ## Incremental build + run the test suite (the inner loop)
	$(DOCKER_RUN) bash /io/scripts/in_container_test.sh

test: dev ## Alias for dev

check: ## Coverage of the app's symbol inventory, against the in-container build
	$(DOCKER_RUN) /cache/venv/bin/python /io/tools/inventory.py --check \
		--inventory /io/inventory.json

sigdiff: ## Diff our bound surface against the stock wheel's (needs the app venv)
	cd $(REPO)/../app && uv run --project backend python \
		$(REPO)/tools/sigdiff.py --dump $(CACHE)/sig-stock.json
	$(DOCKER_RUN) /cache/venv/bin/python /io/tools/sigdiff.py \
		--dump /cache/sig-ours.json
	python3 $(REPO)/tools/sigdiff.py --compare \
		$(CACHE)/sig-stock.json $(CACHE)/sig-ours.json

shell: ## Interactive shell in the builder image
	docker run --rm -it -v $(REPO):/io -v $(CACHE):/cache $(IMAGE) bash

stubs: ## Regenerate .pyi stubs from the built extension
	$(DOCKER_RUN) bash /io/scripts/stubgen.sh

publish: ## Publish wheelhouse/*.whl to the Gitea package registry
	@test -f .secrets || { echo "missing .secrets (UV_PUBLISH_USERNAME/PASSWORD)"; exit 1; }
	set -a; . ./.secrets; set +a; \
	uv publish --publish-url $(PUBLISH_URL) wheelhouse/*.whl

version: ## Print the wheel version
	@grep '^version' pyproject.toml | head -1 | cut -d'"' -f2

clean: ## Remove build output (keeps the docker cache volume)
	rm -rf build dist wheelhouse python/OCP/*.pyi python/n3xd_ocp/*.pyi

clean-cache: ## Drop the persistent build cache
	rm -rf $(CACHE)/ccache $(CACHE)/skbuild $(CACHE)/pip

test-asan: ## Run the handle tests under AddressSanitizer
	$(DOCKER_RUN) bash /io/scripts/asan.sh
