# One target per ctrl/ script; the subcommand is an argument, not a second
# target: `make estate show`, not `make estate-show`. The logic lives in the
# scripts, never here.
#
# Config layers, weakest first: ctrl/versions.env < ctrl/env.d/<target>.env <
# ctrl/.env < the environment. So `make estate plan TARGET=gcp` beats all.
#
# Every target defaults to its READ-ONLY verb, and the verbs that change a live
# estate are not reachable by a bare word. Rationale: README.md.

ESTATE := $(or $(shell sed -n 's/^ESTATE=//p' ctrl/.env 2>/dev/null),$(shell ls estate/*.json 2>/dev/null | head -1 | xargs -r basename | sed 's/\.json$$//'))
TARGET := $(or $(shell sed -n 's/^TARGET=//p' ctrl/.env 2>/dev/null),aws)

.PHONY: help check selftest estate services vpn dns certs host ports registry docs

help:                          ## list targets
	@grep -hE '^[a-z][a-z-]*:.*?##' $(MAKEFILE_LIST) | sed 's/:.*##/\t/' | expand -t16

# ── preflight ──────────────────────────────────────────────────────────────

check:                         ## is this estate coherent? reports, never fixes
	bash ctrl/check.sh

selftest:                      ## does berth still do what it says? exits 1 if not
	bash ctrl/selftest.sh

ports:                         ## port map  [show|verify]  (default show)
	bash ctrl/ports.sh $(or $(ARGS),show)

# ── the estate ─────────────────────────────────────────────────────────────

estate:                        ## the estate  [show|list|plan|apply|destroy]  (default show)
	bash ctrl/estate.sh $(or $(ARGS),show)

services:                      ## gateway routes  [list|render <target>|deploy]  (default list)
	bash ctrl/services.sh $(or $(ARGS),list)

# ── the network ────────────────────────────────────────────────────────────

vpn:                           ## overlays  [list|show <ov>|check|render|keygen]  (default list)
	bash ctrl/vpn.sh $(or $(ARGS),list)

# ── names and trust ────────────────────────────────────────────────────────

dns:                           ## DNS records  [list|add|add-wildcard|remove]  (default list)
	bash ctrl/dns.sh $(or $(ARGS),list)

certs:                         ## TLS  [status|verify|renew|push]  (default status)
	bash ctrl/certs.sh $(or $(ARGS),status)

# ── the box ────────────────────────────────────────────────────────────────

host:                          ## the remote box  [status|ports|services]  (default status)
	bash ctrl/host.sh $(or $(ARGS),status)

registry:                      ## the image registry  [status]  (default status)
	bash ctrl/registry.sh $(or $(ARGS),status)

# ── docs ───────────────────────────────────────────────────────────────────

docs:                          ## documentation  [serve|graphs]  (default serve)
	bash ctrl/docs.sh $(or $(ARGS),serve)

# ── swallowing the argument words — MUST BE LAST IN THIS FILE ──────────────
#
# Words after the target are arguments, but make reads each as a goal, so each
# gets a no-op rule. This block must come AFTER the real targets: when an
# argument names one (`make host ports`, `make vpn check`), the last definition
# wins, and it has to be the no-op. With it first, make ran both scripts.
#
# Make's "overriding recipe" warning is the swallow working as intended.
ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
ifneq ($(ARGS),)
$(eval $(ARGS):;@:)
# .PHONY too: some of those words name real directories (ctrl, estate, render),
# and make treats an existing directory as already built.
.PHONY: $(ARGS)
endif
