HUGO     := hugo
PAGEFIND := npx -y pagefind
LYCHEE   := lychee
OUT      := public

# --- Pinned toolchain (repo-local .tools/; gitignored) ---
# `make bootstrap` installs these exact versions into .tools/bin. The PATH
# prepend below applies to every recipe, so make targets always use the pinned
# tools; your system PATH is never modified. `make tool-versions` shows both.
HUGO_VERSION   := 0.167.0
NODE_VERSION   := 22.11.0
LYCHEE_VERSION := 0.24.2
TOOLS_BIN      := $(CURDIR)/.tools/bin
export PATH    := $(TOOLS_BIN):$(PATH)

.PHONY: all build index serve run link-check link-fix external-check external-fix external-fix-apply serve-lan clean bootstrap tool-versions preflight

all: index

# ONE-TIME per machine: install the pinned hugo/node/lychee into .tools/bin.
# Idempotent (present-at-pin tools are skipped); touches nothing outside .tools/.
bootstrap:
	scripts/bootstrap.sh

# Diagnostic: pinned (.tools/bin) vs PATH-first (system) tool versions.
tool-versions:
	scripts/tool_versions.sh

# Strict tool check; runs automatically before all/serve/serve-lan and
# fails with a `make bootstrap` hint instead of a bare "error 127".
preflight:
	scripts/tool_versions.sh --strict

# Build Hugo content -> public/ (preflight first so a missing tool fails fast
# and in order even under `make -j`).
build: preflight
	$(HUGO) --gc

# (Re)build the Pagefind search index from public/ -> public/pagefind/
index: build
	$(PAGEFIND) --site $(OUT)

# Build content + index, then serve the built site WITH search on :1414 (dev preview).
# Uses pagefind's own server. Local only (binds 127.0.0.1) -- for LAN use `make serve-lan`.
serve: index
	$(PAGEFIND) --site $(OUT) --serve

run: serve

# DEAD LINKS -- internal (offline, fast): scan the SOURCE markdown; internal links
# resolve to file:// under public/. External links are skipped by --scheme file.
# Output: linkcheck/internal.json (exit != 0 when dead links exist; that is fine).
link-check: build
	mkdir -p linkcheck
	$(LYCHEE) --root-dir $(OUT) --default-extension html --scheme file \
	  --format json --timeout 10 \
	  $(wildcard content/*.md) $(wildcard content/*/*.md) > linkcheck/internal.json

# Comment out confirmed dead INTERNAL page links, then rebuild content + index so they
# leave the live page AND the search index. (External failures -> manual_review.txt.)
link-fix:
	python3 scripts/fix_dead_links.py --report linkcheck/internal.json --apply
	$(HUGO) --gc
	$(PAGEFIND) --site $(OUT)

# DEAD LINKS -- external (network): scan all http/https links in content. Report-only.
# Always exits 0; the report is the point. Also saves the full lychee JSON to
# linkcheck/external.json so external-fix can act without re-pinging the web.
external-check:
	python3 scripts/check_external_links.py

# Preview which EXTERNAL links are truly dead (domain/DNS no longer exists) and
# would be commented out. Reports only; changes nothing. Run external-check first.
external-fix:
	python3 scripts/fix_dead_external_links.py --report linkcheck/external.json

# Comment out the truly-dead EXTERNAL links (DNS failed / host unreachable), then
# rebuild content + index so they leave the live page AND the search index.
# 404s, SSL errors, 5xx, redirects, refused/reset connections are NOT auto-commented
# (domain is still alive / ambiguous) -- they go to linkcheck/manual_review_external.txt.
external-fix-apply:
	python3 scripts/fix_dead_external_links.py --report linkcheck/external.json --apply
	$(HUGO) --gc
	$(PAGEFIND) --site $(OUT)

# Serve the BUILT site on all interfaces so another LAN machine can open it:
#   http://<this-machine-LAN-IP>:8090/    (IP printed at startup; also `hostname -I | head -1`)
serve-lan: preflight
	python3 scripts/serve_lan.py

# NOTE: clean does NOT remove .tools/ -- the pinned toolchain is expensive to
# reinstall and independent of build output. Remove it manually if ever needed.

clean:
	rm -rf $(OUT) linkcheck
