.PHONY: help install test lint fmt up down logs ui-install ui-build integration odcs-lint db-migrate reseed clean

help:
	@echo "install     - pip install -e .[dev]"
	@echo "test        - run unit tests"
	@echo "lint        - ruff + mypy"
	@echo "fmt         - ruff format"
	@echo "up/down     - start/stop the docker stack (Airflow 3 + Postgres)"
	@echo "logs        - tail the Airflow container logs"
	@echo "ui-build    - build the React plugin views"
	@echo "integration - full end-to-end test: compose up, run demo DAG, assert results, compose down -v"
	@echo "db-migrate  - apply pending DQ schema migrations against DQ_RESULTS_DSN"
	@echo "reseed      - drop + reload the dirty demo data in dq-postgres"
	@echo "clean       - remove build/test artifacts (dist, caches, coverage)"

install:
	python -m pip install -e ".[dev]"

test:
	pytest

lint:
	ruff check src tests
	mypy src

fmt:
	ruff format src tests
	ruff check --fix src tests

up:
	docker compose up -d

down:
	docker compose down

logs:
	docker compose logs -f airflow

ui-install:
	cd ui && npm install

ui-build:
	cd ui && npm run build

# Same flow as the CI integration job (scripts/integration_test.sh):
# compose up -> wait healthy -> trigger demo_medallion -> assert dq_check_results rows -> down -v.
# KEEP_STACK=1 make integration  leaves the stack running for debugging.
integration:
	bash scripts/integration_test.sh

# ODCS v3.1 spec compliance via the official datacontract-cli (pip install datacontract-cli).
odcs-lint:
	bash scripts/odcs_lint.sh

# Apply pending SQL migrations (src/airflow_dq/results/migrations/) to the results DB.
# Target DB comes from DQ_RESULTS_DSN (defaults to the compose demo DSN); when running
# against the compose stack from the host, use the published port:
#   DQ_RESULTS_DSN=postgresql+psycopg2://dq:dq@localhost:5433/dq make db-migrate
db-migrate:
	python -c "\
	from airflow_dq.config import settings; \
	from airflow_dq.db import get_engine; \
	from airflow_dq.results.migrator import ensure_schema; \
	applied = ensure_schema(get_engine(settings().results_dsn)); \
	print('applied:', ', '.join(applied) if applied else 'nothing (schema is current)')"

# Drop and reload the intentionally-dirty demo table so check outcomes stop drifting
# as the volume ages (seed dates are relative to load time).
reseed:
	docker compose exec -T dq-postgres psql -U dq -d dq -c "DROP TABLE IF EXISTS orders"
	docker compose exec -T dq-postgres psql -U dq -d dq -v ON_ERROR_STOP=1 -f - < seeds/dirty_orders.sql

clean:
	rm -rf dist build src/*.egg-info .pytest_cache .mypy_cache .ruff_cache .coverage htmlcov
	find . -name __pycache__ -not -path "./ui/node_modules/*" -type d -exec rm -rf {} +
