.PHONY: all frontend backend backend-debug backend-pam release catools test cover bench race lint fmt clean run

# --------------------------------------------------------------------------- #
# Sources — adding any file here triggers a frontend or backend rebuild        #
# --------------------------------------------------------------------------- #

FRONTEND_SRCS := $(shell find web/src -name '*.tsx' -o -name '*.ts' -o -name '*.css') \
                 $(wildcard web/vendor/*.mjs web/vendor/*.js web/vendor/*.css) \
                 tools/buildfrontend/main.go

GO_SRCS := $(shell find cmd internal -name '*.go') \
           $(shell find pkg/ca -name '*.go') \
           web/embed.go go.mod go.sum go.work

# --------------------------------------------------------------------------- #
# Outputs                                                                      #
# --------------------------------------------------------------------------- #

FRONTEND_OUT := web/dist/main.js
BINARY       := dist/uopi
CATOOLS      := dist/catools

# --------------------------------------------------------------------------- #
# Top-level targets                                                            #
# --------------------------------------------------------------------------- #

all: $(BINARY) $(CATOOLS)

frontend: $(FRONTEND_OUT)

backend: $(BINARY) $(CATOOLS)

# --------------------------------------------------------------------------- #
# Build rules                                                                  #
# --------------------------------------------------------------------------- #

# Bundle TypeScript/TSX → web/dist/ using esbuild (pure Go, no npm)
$(FRONTEND_OUT): $(FRONTEND_SRCS)
	@mkdir -p web/dist
	go run ./tools/buildfrontend/main.go

# Compile the self-contained binary (embeds web/dist at build time).
# Pure-Go CA client (pkg/ca) is always used; CGO_ENABLED=0 produces a fully
# static binary with no external library dependencies.
$(BINARY): $(GO_SRCS) $(FRONTEND_OUT)
	@mkdir -p dist
	CGO_ENABLED=0 go build -ldflags="-s -w" -o $(BINARY) ./cmd/uopi

# CA diagnostic tools (caget/caput/cainfo/camonitor equivalents)
$(CATOOLS): $(GO_SRCS)
	@mkdir -p dist
	CGO_ENABLED=0 go build -ldflags="-s -w" -o $(CATOOLS) ./cmd/catools

# PAM-enabled binary: adds built-in HTTP Basic authentication validated against
# the host PAM stack (server.basic_auth). Requires cgo + libpam (-dev headers),
# so the resulting binary is NOT fully static — use only when basic_auth is needed.
backend-pam: $(FRONTEND_OUT)
	@mkdir -p dist
	CGO_ENABLED=1 go build -tags pam -ldflags="-s -w" -o $(BINARY) ./cmd/uopi
	CGO_ENABLED=0 go build -ldflags="-s -w" -o $(CATOOLS) ./cmd/catools

# Unstripped binary for debugging (pure-Go CA, CGO_ENABLED=0)
backend-debug: $(FRONTEND_OUT)
	@mkdir -p dist
	CGO_ENABLED=0 go build -o $(BINARY) ./cmd/uopi
	CGO_ENABLED=0 go build -o $(CATOOLS) ./cmd/catools

# --------------------------------------------------------------------------- #
# Release                                                                      #
# --------------------------------------------------------------------------- #
#
# Fully static, pure-Go CA client, no external library dependencies.
# Cross-compile: make release RELEASE_OS=linux RELEASE_ARCH=arm64

RELEASE_OS   ?= linux
RELEASE_ARCH ?= amd64
RELEASE_DIR  := dist/release

release: $(FRONTEND_OUT)
	@mkdir -p $(RELEASE_DIR)
	CGO_ENABLED=0 GOOS=$(RELEASE_OS) GOARCH=$(RELEASE_ARCH) \
	  go build -ldflags="-s -w" -o $(RELEASE_DIR)/uopi ./cmd/uopi
	@echo "Built: $(RELEASE_DIR)/uopi  (static, pure-Go CA)"

# --------------------------------------------------------------------------- #
# Dev / CI                                                                     #
# --------------------------------------------------------------------------- #

test:
	go test ./...
	cd pkg/ca && go test ./...
	cd pkg/pva && go test ./...

# Run tests with the race detector enabled.
race:
	go test -race ./...
	cd pkg/ca && go test -race ./...
	cd pkg/pva && go test -race ./...

# Run the main module's tests with coverage and print the total.
cover:
	go test -coverprofile=coverage.out ./...
	go tool cover -func=coverage.out | tail -1

# Run all benchmarks and print memory allocations.
bench:
	go test -bench=. -benchmem -benchtime=3s ./internal/...

lint:
	go vet ./...

# Rewrite all Go sources in canonical gofmt form (matches the CI gofmt gate).
fmt:
	gofmt -w $(shell git ls-files '*.go')

run: $(BINARY)
	$(BINARY)

catools: $(CATOOLS)

clean:
	rm -rf dist/ web/dist/
