.PHONY: help
help: ## Display this help.
	@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf "  \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

.PHONY: install-go
install-go: ## Install Go dependencies
	go mod download

.PHONY: install
install: install-go ## Install all dependencies
	cd web && pnpm install --frozen-lockfile

.PHONY: generate-bpf
generate-bpf: ## Compile the heimdall eBPF program and regenerate Go bindings (uses pinned clang/Go in docker for bytewise reproducibility across hosts)
	@docker build --platform=linux/amd64 -q -t teral-bpf-gen -f svc/heimdall/internal/network/bpf/Dockerfile.gen svc/heimdall/internal/network/bpf >/dev/null
	@docker run --rm --platform=linux/amd64 -v "$$PWD:/work" -w /work teral-bpf-gen \
		go generate -tags bpf_generate ./svc/heimdall/internal/network/...

.PHONY: dev
dev: ## Start dev environment
	@ctlptl apply -f ./dev/cluster.yaml
	@minikube addons enable metrics-server
	@tilt up -f ./dev/Tiltfile

.PHONY: oci-load
oci-load: build ## Build and load OCI images into Docker
	bazel run //:oci_load_teral

.PHONY: local-dashboard
local-dashboard: install oci-load ## Run local development setup for dashboard
	pnpm --dir=web/apps/dashboard local

.PHONY: build
build:  ## Build all artifacts
	bazel build //...

.PHONY: down
down: ## Stop tilt (keeps cluster)
	@tilt down -f ./dev/Tiltfile

.PHONY: nuke
nuke: ## Delete minikube cluster entirely
	@minikube delete

.PHONY: fmt-yaml
fmt-yaml: ## Format YAML files
	dprint fmt --config dev/dprint.json

.PHONY: fmt
fmt: fmt-yaml ## Format code
	go fmt ./...
	go tool buf format -w

	cd web && pnpm fmt

.PHONY: teral
teral:
	@set -a; [ -f .env ] && . ./.env; set +a; bazel run --ui_event_filters=-info --noshow_progress //:teral -- $(filter-out teral,$(MAKECMDGOALS)) $(ARGS)

# Catch-all to swallow extra args passed to teral target (only when teral is called)
ifneq ($(filter teral,$(MAKECMDGOALS)),)
%:
	@:
endif

.PHONY: generate-api-sdk
generate-api-sdk: ## Regenerate the dashboard TypeScript SDK (web/internal/api) from the OpenAPI spec
	./tools/generate-api-sdk.sh

.PHONY: generate-sql
generate-sql: ## Regenerate pkg/mysql/schema/*.sql from the drizzle schema
	@rm -rf ./web/internal/db/out
	@rm -f ./pkg/mysql/schema/*.sql
	@mkdir -p ./pkg/mysql/schema
	@cd web/internal/db && pnpm drizzle-kit generate --schema=src/schema/index.ts --dialect=mysql --out=out --name=init --breakpoints=true
	@awk -v dir=./pkg/mysql/schema 'BEGIN{RS="--> statement-breakpoint"} \
		/^[[:space:]]*$$/{next} \
		{ gsub(/^[[:space:]]+|[[:space:]]+$$/, ""); \
		  table=""; \
		  if ($$0 ~ /^CREATE TABLE/) { s=$$0; gsub(/^CREATE TABLE `/, "", s); gsub(/`.*/, "", s); table=s } \
		  else if ($$0 ~ /ON `/) { s=$$0; gsub(/.*ON `/, "", s); gsub(/`.*/, "", s); table=s } \
		  if (table != "") { f=dir "/" table ".sql"; print $$0 "\n" >> f } }' \
		./web/internal/db/out/0000_init.sql
	@rm -rf ./web/internal/db/out

.PHONY: generate-oneof
generate-oneof: ## Export unexported protobuf oneof interfaces as public aliases
	go run ./tools/exportoneof ./gen/proto
