# Makefile for harness-gateway
# Usage:
#   make              - Show this help
#   make all          - lint + typecheck + test (CI ship bar)
#   make build        - Build Python wheel + sdist
#   make publish      - Build + upload to PyPI
#
# Prerequisites:
#   - Python 3.11+
#   - uv              (recommended) or pip
#   - twine           (publish: pip install twine / make install-tools)

SHELL := /bin/bash
.DEFAULT_GOAL := help

REPO_ROOT := $(shell pwd)
DIST_DIR  := $(REPO_ROOT)/dist

# PyPI repository (override: make publish PYPI_REPO=testpypi)
PYPI_REPO  ?= pypi
PYPI_TOKEN ?=

# Prefer uv when available; fall back to plain commands (CI / pip install -e ".[dev]")
UV     := $(shell command -v uv 2>/dev/null)
RUN    := $(if $(UV),uv run,)
PYTHON := $(if $(UV),uv run python,python3)
PIP    := $(if $(UV),uv pip,python3 -m pip)

# ─── Help ────────────────────────────────────────────────────────────────────

.PHONY: help
help:
	@echo "harness-gateway Build System"
	@echo ""
	@echo "Usage: make <target>"
	@echo ""
	@echo "Build targets:"
	@echo "  build            Build Python wheel + sdist"
	@echo ""
	@echo "Publish targets:"
	@echo "  publish          Build + upload to PyPI (PYPI_TOKEN or prompt)"
	@echo "  publish-test     Build + upload to TestPyPI"
	@echo ""
	@echo "Quality targets (CI ship bar):"
	@echo "  all              lint + typecheck + test"
	@echo "  lint             Ruff check + format check (src, tests)"
	@echo "  format           Ruff auto-fix + format (src, tests)"
	@echo "  typecheck        mypy --strict src"
	@echo "  test             pytest -m \"not integration\""
	@echo "  test-integration pytest -m integration"
	@echo ""
	@echo "Utility targets:"
	@echo "  install          Install Python dev dependencies (alias: install-dev)"
	@echo "  install-dev      uv sync --extra dev / pip install -e \".[dev]\""
	@echo "  install-tools    Install build + twine for publishing"
	@echo "  clean            Remove build artifacts and caches"
	@echo "  version          Show current project version"

# ─── Build ───────────────────────────────────────────────────────────────────

.PHONY: build
build:
	@echo "[build] Cleaning previous build artifacts..."
	rm -rf $(DIST_DIR)/*
	rm -rf $(REPO_ROOT)/build
	@echo "[build] Building wheel + sdist..."
ifdef UV
	uv build --out-dir $(DIST_DIR) .
else
	$(PIP) install --quiet build
	$(PYTHON) -m build --no-isolation --outdir $(DIST_DIR) .
endif
	@echo "[build] Done. Artifacts in: $(DIST_DIR)/"
	@ls -lh $(DIST_DIR)/

# ─── Publish ─────────────────────────────────────────────────────────────────

.PHONY: publish
publish: build
	@echo "[publish] Uploading to $(PYPI_REPO)..."
	@if ! command -v twine > /dev/null 2>&1; then \
		echo "[publish] twine not found. Installing..."; \
		$(PIP) install --quiet twine; \
	fi
	@_token="$(PYPI_TOKEN)"; \
	if [ -z "$$_token" ]; then \
		echo ""; \
		printf "  PYPI_TOKEN is not set. Enter your PyPI API token (pypi-xxx): "; \
		read -r _token; \
		if [ -z "$$_token" ]; then \
			echo "[publish] No token provided. Aborting."; \
			exit 1; \
		fi; \
	fi; \
	$(if $(UV),uv run,) twine upload \
		$(if $(filter testpypi,$(PYPI_REPO)),--repository testpypi,) \
		--username __token__ --password "$$_token" \
		$(DIST_DIR)/*
	@echo "[publish] Upload complete."

.PHONY: publish-test
publish-test:
	$(MAKE) publish PYPI_REPO=testpypi

# ─── Quality ─────────────────────────────────────────────────────────────────

.PHONY: all
all: lint typecheck test

.PHONY: lint
lint:
	@echo "[lint] Ruff check..."
	$(RUN) ruff check src tests
	@echo "[lint] Ruff format check..."
	$(RUN) ruff format --check src tests

.PHONY: format
format:
	@echo "[format] Ruff fix + format..."
	$(RUN) ruff check --fix src tests
	$(RUN) ruff format src tests

.PHONY: typecheck
typecheck:
	@echo "[typecheck] mypy..."
	$(RUN) mypy src

.PHONY: test
test:
	@echo "[test] pytest (not integration)..."
	$(RUN) pytest -m "not integration"

.PHONY: test-integration
test-integration:
	@echo "[test] pytest (integration)..."
	$(RUN) pytest -m integration

# ─── Utilities ───────────────────────────────────────────────────────────────

.PHONY: install install-dev
install install-dev:
	@echo "[install] Installing Python dev dependencies..."
ifdef UV
	uv sync --extra dev
else
	$(PIP) install -e ".[dev]"
endif

.PHONY: install-tools
install-tools:
	$(PIP) install --quiet build twine
	@echo "[install-tools] build and twine installed."

.PHONY: clean
clean:
	@echo "[clean] Removing build artifacts..."
	rm -rf $(DIST_DIR)/*
	rm -rf $(REPO_ROOT)/build
	rm -rf $(REPO_ROOT)/*.egg-info
	rm -rf $(REPO_ROOT)/src/*.egg-info
	rm -rf $(REPO_ROOT)/.mypy_cache $(REPO_ROOT)/.ruff_cache $(REPO_ROOT)/.pytest_cache
	rm -rf $(REPO_ROOT)/htmlcov $(REPO_ROOT)/.coverage
	find $(REPO_ROOT)/src -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
	@echo "[clean] Done."

.PHONY: version
version:
	@$(PYTHON) -c "import pathlib, re; t = pathlib.Path('pyproject.toml').read_text(); m = re.search(r'^version\\s*=\\s*\"([^\"]+)\"', t, re.M); print(m.group(1) if m else 'unknown')"
