# Makefile for Firehose monorepo

MISE_BIN ?= mise

.PHONY: check precommit verify hooks deps setup compile test test-elisp format

# Cheap static gate over both apps, cheapest first. No database, no coverage:
# this is the loop you run freely while working and before every commit.
check:
	@echo "==> check: app (credo --strict, format)"
	@$(MAKE) -C app MISE_BIN=$(MISE_BIN) check
	@echo "==> check: blogex (compile, format)"
	@$(MAKE) -C blogex MISE_BIN=$(MISE_BIN) check
	@echo "==> check: toolchain pins"
	@bash scripts/check-pins.sh
	@echo "==> check: Lens sensor wiring"
	@bash scripts/check-lens-sensors.sh

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

# The Lens pass: everything `check` does, plus, per app, one suite run (which
# exports its coverage) and that app's sensors reading the export. Sensors run
# cheapest-first among themselves. `.githooks/pre-push` runs this before every
# push (see `make hooks`); run it yourself before handing off. Bypass
# deliberately with `git push --no-verify`.
verify: check
	@echo "==> verify: app"
	@$(MAKE) -C app MISE_BIN=$(MISE_BIN) verify
	@echo "==> verify: blogex"
	@$(MAKE) -C blogex MISE_BIN=$(MISE_BIN) verify

# Install the versioned hooks in .githooks/ into this clone's hooks directory as
# symlinks (edits take effect immediately, no copy to drift). Idempotent; re-run
# after moving the clone, since the links are absolute.
#
# core.hooksPath is deliberately NOT changed: bd manages its own hooks inside
# .git/hooks (pre-commit flushes .beads/issues.jsonl, post-merge imports it) and
# moving the hooks path would silently retire them.
hooks:
	@hooks_dir=$$(git rev-parse --git-path hooks); \
	root=$$(git rev-parse --show-toplevel); \
	mkdir -p "$$hooks_dir"; \
	for hook in .githooks/*; do \
		name=$$(basename "$$hook"); \
		ln -sfn "$$root/$$hook" "$$hooks_dir/$$name"; \
		echo "installed $$hooks_dir/$$name -> $$hook"; \
	done

# One-time setup for this clone (and after any mix.exs gains a dependency):
# fetches Hex deps for both apps and the app's JS packages. Needs network, and
# is deliberately NOT wired into check/test/verify: `mix deps.get` contacts
# hex.pm even when everything is already installed (the advisory check), which
# fails offline/sandboxed. The everyday loops run the per-app `deps.check`
# guard instead and point here when deps are missing.
setup:
	@$(MAKE) -C app MISE_BIN=$(MISE_BIN) deps
	@$(MAKE) -C blogex MISE_BIN=$(MISE_BIN) deps

# Kept for muscle memory; `setup` is the canonical entry point.
deps: setup

# Compile the project
compile:
	@make -C app compile

# Run tests (app suite + blogex library suite)
test:
	@make -C app test
	@make -C blogex test

# Run Emacs Lisp tests for roam-export-blog (requires emacs on PATH)
test-elisp:
	emacs --batch -Q -l org -l ox-md -l scripts/roam-export-blog.el -l scripts/roam-export-blog-test.el -f ert-run-tests-batch-and-exit

# Format code in both apps. Mutating convenience target: `check` (and so
# `verify`) never writes. If a gate fails on formatting, run this.
format:
	@$(MAKE) -C app MISE_BIN=$(MISE_BIN) format
	@$(MAKE) -C blogex MISE_BIN=$(MISE_BIN) format

# Serve the app
serve:
	@cd app && mix phx.server

# Run Playwright browser-based tests (requires running server)
# Set PLAYWRIGHT_BASE_URL to point at the running Phoenix app
playwright:
	@make -C app playwright

# Run Playwright in UI mode (headed browser)
playwright-ui:
	@make -C app playwright-ui

# Run Playwright against Docker Chrome container (must be running)
playwright-docker:
	@make -C app playwright-docker

# Full e2e workflow: start Chrome container, run tests, stop container
playwright-full:
	@make -C app playwright-full

# Start Docker Chrome container
playwright-docker-start:
	@make -C app playwright-docker-start

# Stop Docker Chrome container
playwright-docker-stop:
	@make -C app playwright-docker-stop
