# -----------------------------
# CONFIG
# -----------------------------
-include .env

IMAGE_NAME ?= pgcommon-migrate
BUILD_VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)

LINT_PATHS := src tests

.PHONY: setup install help \
        lint format format-check typecheck vulncheck \
        test-unit test-int test-e2e test-all cover \
        build \
        docker-build lint-docker scan smoke-test \
        docker-up docker-up-all docker-down docker-logs \
        ci clean

# -----------------------------
# SETUP
# -----------------------------

setup: install
	@test -f .env || cp .env-example .env
	@echo "Environment ready (.env, dependencies installed)"

install:
	uv sync

help:
	@echo "Available commands:"
	@echo " make setup         - uv sync + copy .env-example to .env if missing"
	@echo " make install       - uv sync only"
	@echo " make lint          - ruff check"
	@echo " make format        - ruff format + ruff check --fix (rewrites files)"
	@echo " make format-check  - ruff format --check (no changes; used in CI)"
	@echo " make typecheck     - mypy --strict"
	@echo " make vulncheck     - pip-audit against locked dependencies"
	@echo " make test-unit     - unit tests only (no Docker required)"
	@echo " make test-int      - integration tests (requires Docker — spins up Postgres)"
	@echo " make test-e2e      - e2e tests (requires Docker — spins up Postgres + PgBouncer)"
	@echo " make test-all      - unit + integration + e2e in one pytest run"
	@echo " make cover         - test-all + open an HTML coverage report (>=97% gate enforced by pyproject.toml)"
	@echo " make build         - build the wheel + sdist into dist/ (uv build) and verify the migrate CLI installs"
	@echo " make docker-build  - build the migrate-CLI image locally"
	@echo " make lint-docker   - hadolint against Dockerfile (matches CI's 'Lint Dockerfile' check)"
	@echo " make scan          - build + Trivy CVE scan (matches CI's 'Trivy CVE scan' check)"
	@echo " make smoke-test    - build, run, and verify the migrate CLI image (matches CI's 'Smoke tests')"
	@echo " make docker-up     - start Postgres only (for test-int)"
	@echo " make docker-up-all - start Postgres + PgBouncer (for test-e2e)"
	@echo " make docker-down   - stop and remove local Postgres/PgBouncer containers"
	@echo " make docker-logs   - tail logs from the local Postgres/PgBouncer containers"
	@echo " make ci            - full local pipeline (format-check + lint + typecheck + test-all + build)"
	@echo " make clean         - remove venv, caches, build artifacts, and coverage output"

# -----------------------------
# PYTHON BASICS (uv-managed: .venv + uv.lock)
# -----------------------------

lint:
	uv run ruff check $(LINT_PATHS)

format:
	uv run ruff format $(LINT_PATHS)
	uv run ruff check --fix $(LINT_PATHS)

format-check:
	uv run ruff format --check $(LINT_PATHS)

typecheck:
	uv run mypy

vulncheck:
	uv run pip-audit

# -----------------------------
# TESTS
# -----------------------------

test-unit:
	uv run pytest tests/unit -v

test-int:
	uv run pytest tests/integration -v -m integration

test-e2e:
	uv run pytest tests/e2e -v -m e2e

test-all:
	uv run pytest tests/unit tests/integration tests/e2e -v

# Coverage gate (>=97%) is enforced by pyproject.toml's [tool.coverage.report] fail_under,
# applied automatically via pytest's default addopts — this target just also opens an
# HTML report.
cover: test-all
	uv run coverage html
	@echo "HTML coverage report: htmlcov/index.html"

# -----------------------------
# BUILD
# -----------------------------

build:
	@echo "Building wheel + sdist (version: $(BUILD_VERSION))..."
	uv build
	@ls dist/*.whl dist/*.tar.gz
	@echo "Verifying the pgcommon-migrate console script installs and runs..."
	@rm -rf /tmp/pgcommon-verify-venv
	@python3 -m venv /tmp/pgcommon-verify-venv
	@/tmp/pgcommon-verify-venv/bin/pip install --quiet dist/*.whl
	@/tmp/pgcommon-verify-venv/bin/pgcommon-migrate --help >/dev/null
	@rm -rf /tmp/pgcommon-verify-venv
	@echo "OK"

# -----------------------------
# DOCKER (MIGRATE CLI IMAGE)
# -----------------------------

docker-build:
	@echo "Building migrate CLI image (version: $(BUILD_VERSION))..."
	docker build -t $(IMAGE_NAME):local .

# Requires hadolint (brew install hadolint). Matches CI's "Lint Dockerfile" check exactly.
lint-docker:
	hadolint --failure-threshold warning Dockerfile

# Requires trivy (brew install trivy). Matches CI's "Trivy CVE scan" check exactly:
# fails only on HIGH/CRITICAL vulnerabilities that have an available fix.
scan:
	docker build -t $(IMAGE_NAME):scan .
	trivy image --severity HIGH,CRITICAL --ignore-unfixed --exit-code 1 --scanners vuln $(IMAGE_NAME):scan

# This image is a migrate CLI, not a running service — matches CI's "Smoke tests" job:
# the default CMD prints usage, and a real invocation against a bad migration source
# fails cleanly (non-zero exit, readable error) instead of hanging or crashing.
smoke-test:
	docker build -t $(IMAGE_NAME):smoke .
	docker run --rm $(IMAGE_NAME):smoke | grep -q 'Apply or roll back pgcommon SQL migrations'
	@if docker run --rm $(IMAGE_NAME):smoke --dsn "postgres://x" up 2>&1 | grep -q 'migration source'; then \
		echo "All smoke checks passed"; \
	else \
		echo "Smoke test failed: expected a 'migration source' error" >&2; exit 1; \
	fi

# -----------------------------
# DOCKER (LOCAL POSTGRES / PGBOUNCER FOR INTEGRATION / E2E TESTS)
# -----------------------------

docker-up:
	docker compose up -d postgres
	docker compose exec postgres sh -c 'until pg_isready -U test -d test; do sleep 1; done'

docker-up-all:
	docker compose --profile pgbouncer up -d

docker-down:
	docker compose down -v

docker-logs:
	docker compose logs -f

# -----------------------------
# CI (mirrors .github/workflows/validate.yml + the build job; docker image build/push
# is a separate CI job, not part of the default local loop)
# -----------------------------

ci: format-check lint typecheck test-all build

# -----------------------------
# CLEAN
# -----------------------------

clean:
	rm -rf .venv .pytest_cache .mypy_cache .ruff_cache htmlcov .coverage coverage.xml dist build *.egg-info
