-include .env

GENERATOR_VERSION ?= v7.19.0
TEMPLATES_DIR ?= templates
COMPAT_DIR ?= compat

# Rootless podman (Fedora ships `docker` as a podman shim) maps the
# container UID to a host *subuid*, so a plain `--user $(id -u):$(id -g)`
# runs as a uid that cannot write the host-owned bind-mounted output tree
# (AccessDenied on every generated file). `--userns=keep-id` maps the host
# UID through unchanged so writes land as the invoking user. Real Docker
# neither accepts nor needs this flag, so only add it for podman.
DOCKER ?= docker
USERNS_FLAG := $(shell $(DOCKER) --version 2>/dev/null | grep -qi podman && echo --userns=keep-id)


# v7 generator with backward compatibility patches (offline - no server needed)
generate-openapi-client:
	@echo "Generating OpenAPI 3.1 spec offline..."
	cd ../.. && uv run python scripts/generate_openapi_spec.py > clients/python/openapi.json.tmp
	@echo "Converting to OpenAPI 3.0.3 for generator compatibility..."
	cd ../.. && uv run python scripts/convert_openapi_31_to_30.py < clients/python/openapi.json.tmp > clients/python/openapi.json.30.tmp
	@echo "Modifying server URL to production..."
	jq '.servers[0].url = "https://api.iknaio.com"' openapi.json.30.tmp > openapi.json.modified
	@API_VERSION=$$(jq -r '.info.version' openapi.json.30.tmp) && \
	echo "Generating client with $(GENERATOR_VERSION) (API version: $$API_VERSION, package version: $$API_VERSION)..." && \
	$(DOCKER) run --rm \
		--user $$(id -u):$$(id -g) \
		$(USERNS_FLAG) \
		--security-opt label=disable \
		-v "${PWD}:/build" \
		-v "${PWD}/$(TEMPLATES_DIR):/templates" \
		openapitools/openapi-generator-cli:$(GENERATOR_VERSION) \
		generate -i /build/openapi.json.modified \
		-g python \
		-t /templates \
		-o /build \
		--additional-properties=packageName=graphsense \
		--additional-properties=projectName=graphsense-python \
		--additional-properties=packageVersion=$$API_VERSION \
		--additional-properties=httpUserAgent=graphsense-python/$$API_VERSION \
		--additional-properties=library=urllib3 && \
	echo "Fixing project name and version in pyproject.toml..." && \
	sed -i 's/^name = "graphsense"/name = "graphsense-python"/' pyproject.toml && \
	sed -i "s/^version = .*/version = \"$$API_VERSION\"/" pyproject.toml
	@echo "Applying backward compatibility patches..."
	uv run $(COMPAT_DIR)/patch_compat.py .
	@echo "Verifying backward compatibility..."
	uv run $(COMPAT_DIR)/test_compat.py .
	@echo "Cleaning up temporary files..."
	rm -f openapi.json.tmp openapi.json.30.tmp openapi.json.modified

# Just run the compatibility tests (useful during development)
test-compat:
	uv run $(COMPAT_DIR)/test_compat.py .

# Vendor src/graphsenselib/convert/gs_files into graphsense/gs_files. The
# client is published standalone, so we copy the pure-stdlib module rather
# than depend on graphsenselib. cli.py is excluded — the client has its own
# CLI integration in graphsense/cli/gs.py.
sync-gs-files:
	uv run python scripts/sync_gs_files.py

# Drift check used by pre-commit / CI.
check-gs-files:
	uv run python scripts/sync_gs_files.py --check

# Vendor src/graphsenselib/convert/address_scan into graphsense/address_scan.
# Rewrites the two graphsenselib imports so the client stays standalone
# (validators -> vendored stdlib-only module, lzw_unpack -> graphsense.gs_files).
# cli.py is excluded — the client has its own CLI in graphsense/cli/scan.py.
sync-address-scan:
	uv run python scripts/sync_address_scan.py

# Drift check used by pre-commit / CI.
check-address-scan:
	uv run python scripts/sync_address_scan.py --check

# Offline regression tests for graphsense.ext and the gs CLI.
test:
	uv run --extra cli pytest tests/ -q

# Stricter variant for CI: treats warnings as errors.
test-ci:
	uv run --extra cli pytest tests/ -q -W error

lint:
	uv run --with ruff ruff check graphsense/ext graphsense/cli tests
	uv run --with ruff ruff format --check graphsense/ext graphsense/cli tests

format:
	uv run --with ruff ruff format graphsense/ext graphsense/cli tests
	uv run --with ruff ruff check --fix graphsense/ext graphsense/cli tests

# ty picks up this workspace's first-party paths from --python, and
# we pass explicit files because ty does not yet discover them from
# directories in this mixed-project layout.
type-check:
	uv run --extra cli --with ty ty check --python .venv \
		$$(find graphsense/ext graphsense/cli -name '*.py')

run-examples:
	API_KEY=$(API_KEY) uv run --with pypandoc test_examples.py

.PHONY: generate-openapi-client test-compat test test-ci lint format type-check run-examples sync-gs-files check-gs-files sync-address-scan check-address-scan
