# Makefile for Firehose app

MISE_BIN ?= mise
MISE_EXEC = $(MISE_BIN) exec --

.PHONY: check precommit deps compile test format credo verify

# Run all static analysis checks (no database required)
check: credo format

# Precommit target for CI/pre-commit hooks
precommit: check compile

# Sync dependencies
deps:
	$(MISE_EXEC) mix deps.get

# Compile the project
compile:
	$(MISE_EXEC) mix compile --warnings-as-errors

# Run tests (requires PostgreSQL running on localhost:5432)
# Note: If you don't have PostgreSQL, you can skip tests with `make check`
test: deps compile
	$(MISE_EXEC) mix test

# Format code
format:
	$(MISE_EXEC) mix format

# =============================================================================
# Playwright e2e browser tests
# =============================================================================
#
# Requires the Phoenix dev server running on the default port (8056).
# Set PLAYWRIGHT_BASE_URL to point at a different server/port.
#
# Available browsers (local):
#   PLAYWRIGHT_BROWSER=firefox   (default — works on macOS 15)
#   PLAYWRIGHT_BROWSER=chromium  (crashes on macOS 15, use Docker Chrome)
#   PLAYWRIGHT_BROWSER=webkit
#
# Docker Chrome (alternative):
#   1. docker compose -f docker-compose.chrome.yml up -d
#   2. PLAYWRIGHT_BROWSERS_PATH=assets/node_modules/playwright-core/.local-browsers \
#      npx playwright test --config=playwright.docker.config.ts
#
# =============================================================================

# Run Playwright e2e tests (default: local Firefox)
# Usage: make playwright
#        PLAYWRIGHT_BROWSER=chromium make playwright
playwright:
	cd assets && PLAYWRIGHT_BROWSERS_PATH=node_modules/playwright-core/.local-browsers npx playwright test --config=../playwright.config.ts

# Run a specific Playwright test file
# Usage: make playwright-test test/e2e/smoke.spec.ts
playwright-test:
	cd assets && PLAYWRIGHT_BROWSERS_PATH=node_modules/playwright-core/.local-browsers npx playwright test --config=../playwright.config.ts $(filter-out $@,$(MAKECMDGOALS))

# Run Playwright tests with UI mode (headed browser)
playwright-ui:
	cd assets && PLAYWRIGHT_BROWSERS_PATH=node_modules/playwright-core/.local-browsers npx playwright test --config=../playwright.config.ts --ui

# Show last Playwright HTML report
playwright-report:
	cd assets && npx playwright show-report

# Start Docker Chrome container for remote Playwright
playwright-docker-start:
	docker compose -f docker-compose.chrome.yml up -d

# Stop Docker Chrome container
playwright-docker-stop:
	docker compose -f docker-compose.chrome.yml down

# Run Playwright against Docker Chrome (container must be running)
playwright-docker:
	cd assets && PLAYWRIGHT_BROWSERS_PATH=node_modules/playwright-core/.local-browsers npx playwright test --config=../playwright.docker.config.ts

# Run full end-to-end workflow: start Docker Chrome, run tests, stop container
playwright-full: playwright-docker-start
	@echo "Waiting for Chrome to be ready..."
	@sleep 3
	cd assets && PLAYWRIGHT_BROWSERS_PATH=node_modules/playwright-core/.local-browsers npx playwright test --config=../playwright.docker.config.ts; \
		EXIT_CODE=$$?; \
		cd ..; \
		docker compose -f docker-compose.chrome.yml down; \
		exit $$EXIT_CODE

# =============================================================================
# Static analysis
# =============================================================================

# Run Credo static analysis
credo:
	$(MISE_EXEC) mix credo --strict

# =============================================================================
# Lens pass (heavy checks; root `make verify` runs this before every push)
# =============================================================================
#
# Sensor slots, cheapest first. Credo is cheap enough that it lives in
# `check`, not here. Add a sensor as its yak lands, both as a target and to
# VERIFY_SENSORS — that variable is the single source of truth for what this
# target reports as wired.
#   - sobelow    (yak: sobelow in the Lens pass)
#   - coverage   (yak: coverage floors + framework-glue exclusions policy)
#   - crap       (yak: CRAP scores with ex_crap (both apps))
#   - mutation   (yak: mutation testing with muex — a sensor, not a gate)
#
# Runtime note: the coverage yak should make this export coverage from a single
# suite run (test --cover --export-coverage) that CRAP reuses, instead of
# running the suite twice.
VERIFY_SENSORS :=

verify:
	@echo "==> verify(app): sensors [$(if $(VERIFY_SENSORS),$(VERIFY_SENSORS),none wired yet)]"
	@for sensor in $(VERIFY_SENSORS); do $(MAKE) $$sensor || exit 1; done
	@$(MAKE) test
