# Makefile — MCIAS build, test, lint, and release targets
#
# Usage:
#   make build     — compile all binaries to bin/
#   make test      — run tests with race detector
#   make vet       — run go vet
#   make lint      — run golangci-lint
#   make all       — vet → lint → test → build (CI pipeline)
#   make proto     — regenerate protobuf stubs (requires protoc)
#   make proto-lint — lint proto files with buf
#   make man       — build compressed man pages
#   make install   — run deploy/scripts/install.sh (requires root)
#   make devserver — build and run mciassrv against srv/ config
#   make clean     — remove bin/ and generated artifacts
#   make dist      — build release tarballs for linux/amd64 and linux/arm64
#   make docker    — build Docker image tagged mcias:$(VERSION) and mcias:latest
#   make docker-clean — remove local mcias Docker images

# ---------------------------------------------------------------------------
# Variables
# ---------------------------------------------------------------------------
MODULE     := git.wntrmute.dev/mc/mcias
MCR        := mcr.svc.mcp.metacircular.net:8443
BINARIES   := mciassrv mciasctl mciasdb mciasgrpcctl
BIN_DIR    := bin
MAN_DIR    := man/man1
MAN_PAGES  := $(MAN_DIR)/mciassrv.1 $(MAN_DIR)/mciasctl.1 \
              $(MAN_DIR)/mciasdb.1  $(MAN_DIR)/mciasgrpcctl.1

# Version: prefer git describe; fall back to "dev" when git is unavailable
# or the tree has no tags.
VERSION    := $(shell git describe --tags --always 2>/dev/null || echo dev)

# Build flags: trim paths from binaries and strip DWARF/symbol table.
# modernc.org/sqlite is pure-Go and does not require CGo; CGO_ENABLED=0
# produces statically linked binaries that deploy cleanly to Alpine containers.
GO         := go
GOFLAGS    := -trimpath
LDFLAGS    := -s -w -X main.version=$(VERSION)
CGO        := CGO_ENABLED=0

# The race detector requires CGo on some platforms, so tests continue to use
# CGO_ENABLED=1 while production builds are CGO_ENABLED=0.
CGO_TEST   := CGO_ENABLED=1

# Platforms for cross-compiled dist tarballs.
DIST_PLATFORMS := linux/amd64 linux/arm64

# ---------------------------------------------------------------------------
# Default target — CI pipeline: vet → lint → test → build
# ---------------------------------------------------------------------------
.PHONY: all
all: vet lint test build

# ---------------------------------------------------------------------------
# build — compile all binaries to bin/
# ---------------------------------------------------------------------------
.PHONY: build
build:
	@mkdir -p $(BIN_DIR)
	@for bin in $(BINARIES); do \
		echo "  GO BUILD  cmd/$$bin"; \
		$(CGO) $(GO) build $(GOFLAGS) -ldflags "$(LDFLAGS)" \
			-o $(BIN_DIR)/$$bin ./cmd/$$bin; \
	done

# ---------------------------------------------------------------------------
# test — run all tests with race detector
# ---------------------------------------------------------------------------
.PHONY: test
test:
	$(CGO_TEST) $(GO) test -race ./...

# ---------------------------------------------------------------------------
# vet — static analysis via go vet
# ---------------------------------------------------------------------------
.PHONY: vet
vet:
	$(GO) vet ./...

# ---------------------------------------------------------------------------
# lint — run golangci-lint
# ---------------------------------------------------------------------------
.PHONY: lint
lint:
	golangci-lint run ./...

# ---------------------------------------------------------------------------
# proto-lint — lint and check for breaking changes in proto definitions
# Requires: buf (https://buf.build/docs/installation)
# ---------------------------------------------------------------------------
.PHONY: proto-lint
proto-lint:
	buf lint
	buf breaking --against '.git#branch=master,subdir=proto'

# ---------------------------------------------------------------------------
# proto — regenerate protobuf stubs from proto/ definitions
# Requires: protoc, protoc-gen-go, protoc-gen-go-grpc
# ---------------------------------------------------------------------------
.PHONY: proto
proto:
	$(GO) generate ./...

# ---------------------------------------------------------------------------
# devserver — build and run mciassrv against the local srv/ config
# ---------------------------------------------------------------------------
.PHONY: devserver
devserver: build
	$(BIN_DIR)/mciassrv -config srv/mcias.conf

# ---------------------------------------------------------------------------
# man — build compressed man pages
# ---------------------------------------------------------------------------
.PHONY: man
man: $(patsubst %.1,%.1.gz,$(MAN_PAGES))

%.1.gz: %.1
	gzip -kf $<

# ---------------------------------------------------------------------------
# install — run the installation script (requires root)
# ---------------------------------------------------------------------------
.PHONY: install
install: build
	sh deploy/scripts/install.sh

# ---------------------------------------------------------------------------
# clean — remove build artifacts
# ---------------------------------------------------------------------------
.PHONY: clean
clean:
	rm -rf $(BIN_DIR)
	rm -rf dist/
	rm -f $(patsubst %.1,%.1.gz,$(MAN_PAGES))
	-docker rmi mcias:$(VERSION) mcias:latest 2>/dev/null || true

# ---------------------------------------------------------------------------
# dist — cross-compiled release tarballs for linux/amd64 and linux/arm64
#
# Output files: dist/mcias_<version>_<os>_<arch>.tar.gz
# Each tarball contains: mciassrv, mciasctl, mciasdb, mciasgrpcctl,
#   man pages, and deploy/ files.
# ---------------------------------------------------------------------------
.PHONY: dist
dist: man
	@for platform in $(DIST_PLATFORMS); do \
		os=$$(echo $$platform | cut -d/ -f1); \
		arch=$$(echo $$platform | cut -d/ -f2); \
		outdir=dist/mcias_$$(echo $(VERSION) | tr -d 'v')_$${os}_$${arch}; \
		echo "  DIST      $$platform -> $$outdir.tar.gz"; \
		mkdir -p $$outdir/bin; \
		for bin in $(BINARIES); do \
			CGO_ENABLED=0 GOOS=$$os GOARCH=$$arch $(GO) build \
				$(GOFLAGS) -ldflags "$(LDFLAGS)" \
				-o $$outdir/bin/$$bin ./cmd/$$bin; \
		done; \
		cp -r man $$outdir/; \
		cp -r deploy $$outdir/; \
		tar -czf $$outdir.tar.gz -C dist mcias_$$(echo $(VERSION) | tr -d 'v')_$${os}_$${arch}; \
		rm -rf $$outdir; \
	done

# ---------------------------------------------------------------------------
# docker — build the Docker image
# ---------------------------------------------------------------------------
.PHONY: docker push
docker:
	docker build --force-rm -t $(MCR)/mcias:$(VERSION) .

push: docker
	docker push $(MCR)/mcias:$(VERSION)

# ---------------------------------------------------------------------------
# docker-clean — remove local mcias Docker images
# ---------------------------------------------------------------------------
.PHONY: docker-clean
docker-clean:
	-docker rmi mcias:$(VERSION) mcias:latest 2>/dev/null || true
	-docker image prune -f --filter label=org.opencontainers.image.title=mcias 2>/dev/null || true

.PHONY: install-local
install-local: build
	cp bin/* $(HOME)/.local/bin/

# ---------------------------------------------------------------------------
# Help
# ---------------------------------------------------------------------------
.PHONY: help
help:
	@echo "Available targets:"
	@echo "  all        vet → lint → test → build (CI pipeline)"
	@echo "  build      Compile all binaries to bin/"
	@echo "  test       Run tests with race detector"
	@echo "  vet        Run go vet"
	@echo "  lint       Run golangci-lint"
	@echo "  proto-lint Lint proto files with buf"
	@echo "  proto      Regenerate protobuf stubs"
	@echo "  devserver  Build and run mciassrv against srv/ config"
	@echo "  man        Build compressed man pages"
	@echo "  install    Install to /usr/local/bin (requires root)"
	@echo "  clean      Remove build artifacts"
	@echo "  dist       Build release tarballs for Linux amd64/arm64"
	@echo "  docker     Build Docker image mcias:$(VERSION) and mcias:latest"
	@echo "  docker-clean Remove local mcias Docker images"
