UV ?= uv
PYTHON ?= 3.11
SRC_DIRS := src tests scripts
DEMO_ROOT ?= artifacts/demo
SHOWCASE_ROOT ?= artifacts/showcase
DEMO_IMAGE ?= $(DEMO_ROOT)/dataset/scene-01-orbit.png
DEMO_DATASET ?= $(DEMO_ROOT)/dataset
DEMO_STUDY ?= $(DEMO_ROOT)/study.yaml
DEFAULT_MODEL ?= eupe-vit-b16
COMPARE_MODELS ?= eupe-vit-b16,dinov2-vit-l14
SIM_MODEL_A ?= eupe-vit-b16
SIM_MODEL_B ?= dinov2-vit-l14
CHECKPOINTS_DIR ?= artifacts/checkpoints

.DEFAULT_GOAL := help

.PHONY: help sync lock update format format-check lint lint-fix typecheck test cov check build publish publish-testpypi clean demo-assets smoke demo-models demo-inspect demo-compare demo-profile demo-neighbors demo-similarity demo-study demo-drift showcase-assets showcase

help: ## Show available targets
	@awk 'BEGIN {FS = ":.*## "; printf "\nTargets\n=======\n"} /^[a-zA-Z0-9_.-]+:.*## / {printf "%-20s %s\n", $$1, $$2}' $(MAKEFILE_LIST)

sync: ## Create/update the uv environment with the default dev group
	$(UV) sync --python $(PYTHON) --group dev

lock: ## Generate or refresh uv.lock
	$(UV) lock

update: ## Upgrade locked dependencies
	$(UV) lock --upgrade

format: ## Format the codebase with Ruff
	$(UV) run ruff format $(SRC_DIRS)

format-check: ## Check formatting without modifying files
	$(UV) run ruff format --check $(SRC_DIRS)

lint: ## Run Ruff lint checks
	$(UV) run ruff check $(SRC_DIRS)

lint-fix: ## Apply safe Ruff fixes
	$(UV) run ruff check --fix $(SRC_DIRS)

typecheck: ## Run mypy over the package
	$(UV) run mypy src

test: ## Run the pytest suite
	$(UV) run pytest

cov: ## Run tests with coverage
	$(UV) run pytest --cov=latent_inspector_py --cov-report=term-missing

check: format-check lint typecheck test ## Full local quality gate

build: ## Build wheel and sdist with uv
	$(UV) build

publish-testpypi: ## Publish built artifacts to TestPyPI with uv
	$(UV) publish --publish-url https://test.pypi.org/legacy/

publish: ## Publish built artifacts to PyPI with uv
	$(UV) publish

clean: ## Remove local demo/showcase artifacts and build outputs
	rm -rf dist build .pytest_cache .mypy_cache .ruff_cache $(DEMO_ROOT) $(SHOWCASE_ROOT)

demo-assets: ## Generate a deterministic local showcase dataset and study config
	$(UV) run python scripts/create_demo_assets.py --root $(DEMO_ROOT)

smoke: demo-assets ## Fast dry-run workflow for packaging/export/validation plumbing
	$(UV) run lipy models --format json --output $(DEMO_ROOT)/models
	$(UV) run lipy export onnx --model dinov2-vit-l14 --output $(DEMO_ROOT)/export --dry-run
	$(UV) run lipy validate --model eupe-vit-b16 --output $(DEMO_ROOT)/validation --dry-run --format json

demo-models: ## Print the registry in terminal form
	$(UV) run lipy models --format terminal

demo-inspect: demo-assets ## Inspect one demo image with the default model
	$(UV) run lipy inspect $(DEMO_IMAGE) --model $(DEFAULT_MODEL) --format json --output $(DEMO_ROOT)/inspect

demo-compare: demo-assets ## Compare two models on one demo image
	$(UV) run lipy compare $(DEMO_IMAGE) --models $(COMPARE_MODELS) --format json --output $(DEMO_ROOT)/compare

demo-profile: demo-assets ## Profile a model over the generated demo dataset
	$(UV) run lipy profile --model $(DEFAULT_MODEL) --dataset $(DEMO_DATASET) --format json --output $(DEMO_ROOT)/profile

demo-neighbors: demo-assets ## Run nearest-neighbor search inside the generated demo dataset
	$(UV) run lipy neighbors $(DEMO_IMAGE) --model $(DEFAULT_MODEL) --dataset $(DEMO_DATASET) --k 3 --format json --output $(DEMO_ROOT)/neighbors

demo-similarity: demo-assets ## Measure cross-model similarity over the demo dataset
	$(UV) run lipy similarity --model-a $(SIM_MODEL_A) --model-b $(SIM_MODEL_B) --dataset $(DEMO_DATASET) --metric all --format json --output $(DEMO_ROOT)/similarity

demo-study: demo-assets ## Run the config-driven study over the generated demo dataset
	$(UV) run lipy study run $(DEMO_STUDY)

demo-drift: demo-assets ## Measure checkpoint drift if CHECKPOINTS_DIR contains ONNX checkpoints
	@test -d "$(CHECKPOINTS_DIR)" || (echo "Missing CHECKPOINTS_DIR=$(CHECKPOINTS_DIR)" >&2; exit 1)
	$(UV) run lipy drift --model dinov2-vit-l14 --checkpoints $(CHECKPOINTS_DIR) --dataset $(DEMO_DATASET) --format json --output $(DEMO_ROOT)/drift

showcase-assets: ## Generate a separate dataset tree for showcase outputs
	$(UV) run python scripts/create_demo_assets.py --root $(SHOWCASE_ROOT)

showcase: showcase-assets ## Run a full showcase bundle into artifacts/showcase
	$(UV) run lipy models --format json --output $(SHOWCASE_ROOT)/models
	$(UV) run lipy inspect $(SHOWCASE_ROOT)/dataset/scene-01-orbit.png --model $(DEFAULT_MODEL) --format json --output $(SHOWCASE_ROOT)/inspect
	$(UV) run lipy compare $(SHOWCASE_ROOT)/dataset/scene-01-orbit.png --models $(COMPARE_MODELS) --format json --output $(SHOWCASE_ROOT)/compare
	$(UV) run lipy profile --model $(DEFAULT_MODEL) --dataset $(SHOWCASE_ROOT)/dataset --format json --output $(SHOWCASE_ROOT)/profile
	$(UV) run lipy neighbors $(SHOWCASE_ROOT)/dataset/scene-01-orbit.png --model $(DEFAULT_MODEL) --dataset $(SHOWCASE_ROOT)/dataset --k 3 --format json --output $(SHOWCASE_ROOT)/neighbors
	$(UV) run lipy similarity --model-a $(SIM_MODEL_A) --model-b $(SIM_MODEL_B) --dataset $(SHOWCASE_ROOT)/dataset --metric all --format json --output $(SHOWCASE_ROOT)/similarity
	$(UV) run lipy export onnx --model dinov2-vit-l14 --output $(SHOWCASE_ROOT)/export --dry-run
	$(UV) run lipy validate --model eupe-vit-b16 --output $(SHOWCASE_ROOT)/validation --dry-run --format json
	$(UV) run lipy study run $(SHOWCASE_ROOT)/study.yaml
