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

.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 \
        docker-up docker-down docker-logs run \
        ci clean

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

setup: install
	@test -f .env || cp .env-example .env 2>/dev/null || true
	@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 LocalStack)"
	@echo " make test-e2e      - e2e tests (requires Docker — full publish/outbox/consume pipeline)"
	@echo " make test-all      - unit + integration + e2e in one pytest run"
	@echo " make cover         - test-all + open an HTML coverage report"
	@echo " make build         - build the wheel + sdist into dist/ (uv build)"
	@echo " make docker-build  - build the example outbox-worker 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 docker-up     - start LocalStack + Postgres + the observability stack (Grafana/Tempo/Loki/Prometheus)"
	@echo " make docker-down   - stop and remove the local Docker Compose stack"
	@echo " make docker-logs   - tail logs from the local Docker Compose stack"
	@echo " make run           - docker-up, then build and run the example outbox worker against it"
	@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 src tests

format:
	uv run ruff format src tests
	uv run ruff check --fix src tests

format-check:
	uv run ruff format --check src tests

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 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:
	uv build
	@ls dist/*.whl dist/*.tar.gz

# -----------------------------
# DOCKER (EXAMPLE OUTBOX WORKER + LOCAL INFRA)
# -----------------------------

docker-build:
	docker build -t eventcommon-outbox-worker-example: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 eventcommon-outbox-worker-example:scan .
	trivy image --severity HIGH,CRITICAL --ignore-unfixed --exit-code 1 --scanners vuln eventcommon-outbox-worker-example:scan

# Starts LocalStack (SNS/SQS), Postgres, and the observability stack (otel-collector,
# Tempo, Loki, Promtail, Prometheus, Grafana) — everything test-int/test-e2e and the
# example worker need. The worker itself is under the "demo" profile (see `make run`).
docker-up:
	docker compose up -d localstack postgres otel-collector tempo loki promtail prometheus grafana
	docker compose exec postgres sh -c 'until pg_isready -U eventcommon -d eventcommon; do sleep 1; done'

docker-down:
	docker compose --profile demo down -v

docker-logs:
	docker compose logs -f

# Brings up the full local stack, then builds and runs the example outbox worker
# against it. Grafana: http://localhost:3000 (admin/admin).
run: docker-up
	docker compose --profile demo up --build worker

# -----------------------------
# CI (mirrors .github/workflows/validate.yml + the build job)
# -----------------------------

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
