# Makefile for p4lf — P4 Log Feeder
#
# Common targets:
#   make build          Build for the current platform (output: bin/p4lf)
#   make test           Run all unit tests
#   make vet            Run go vet
#   make fmt            Run gofmt check (no writes; use fmt-fix to apply)
#   make fmt-fix        Run gofmt and rewrite files
#   make clean          Remove build artifacts
#
# Cross-compilation targets:
#   make build-linux        Linux amd64  (primary deployment target)
#   make build-linux-arm64  Linux arm64
#   make build-darwin       macOS arm64  (Apple Silicon dev machines)
#   make build-darwin-amd64 macOS Intel
#   make build-all          All of the above
#
# Install target (Linux only, requires INSTANCE to be set):
#   make install INSTANCE=1
#
# Release:
#   make release VERSION=0.2.0   Build all platforms, create dist/ tarballs

# ── Variables ────────────────────────────────────────────────────────────────

MODULE   := workshop.perforce.com/p4lf
CMD      := ./cmd/p4lf
BIN_NAME := p4lf
BIN_DIR  := bin
DIST_DIR := dist

# Version: read from version.go (the hand-maintained SemVer var).
# Override on the command line to inject a different value at build time:
#   make build VERSION=1.0.0
VERSION  ?= $(shell grep -m1 '^var SemVer' internal/version/version.go | sed 's/.*"\(.*\)".*/\1/')
LDFLAGS  := -ldflags "-X workshop.perforce.com/p4lf/internal/version.SemVer=$(VERSION) -s -w"

# Perforce: capture current default changelist number for release metadata.
P4CL     := $(shell p4 changes -m1 -s submitted //... 2>/dev/null | awk '{print $$2}' || echo "unknown")

# ── Phony targets ─────────────────────────────────────────────────────────────

.PHONY: build build-linux build-linux-arm64 build-darwin build-darwin-amd64 \
        build-all test vet fmt fmt-fix clean install release help

# Default target.
all: build

# ── Build ─────────────────────────────────────────────────────────────────────

## build: Build p4lf for the current platform → bin/p4lf
build:
	@mkdir -p $(BIN_DIR)
	go build $(LDFLAGS) -o $(BIN_DIR)/$(BIN_NAME) $(CMD)
	@echo "Built $(BIN_DIR)/$(BIN_NAME) ($(shell uname -s)/$(shell uname -m), v$(VERSION))"

## build-linux: Cross-compile for Linux amd64 → bin/p4lf-linux-amd64
build-linux:
	@mkdir -p $(BIN_DIR)
	GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o $(BIN_DIR)/$(BIN_NAME)-linux-amd64 $(CMD)
	@echo "Built $(BIN_DIR)/$(BIN_NAME)-linux-amd64 (v$(VERSION))"

## build-linux-arm64: Cross-compile for Linux arm64 → bin/p4lf-linux-arm64
build-linux-arm64:
	@mkdir -p $(BIN_DIR)
	GOOS=linux GOARCH=arm64 go build $(LDFLAGS) -o $(BIN_DIR)/$(BIN_NAME)-linux-arm64 $(CMD)
	@echo "Built $(BIN_DIR)/$(BIN_NAME)-linux-arm64 (v$(VERSION))"

## build-darwin: Cross-compile for macOS arm64 (Apple Silicon) → bin/p4lf-darwin-arm64
build-darwin:
	@mkdir -p $(BIN_DIR)
	GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o $(BIN_DIR)/$(BIN_NAME)-darwin-arm64 $(CMD)
	@echo "Built $(BIN_DIR)/$(BIN_NAME)-darwin-arm64 (v$(VERSION))"

## build-darwin-amd64: Cross-compile for macOS Intel → bin/p4lf-darwin-amd64
build-darwin-amd64:
	@mkdir -p $(BIN_DIR)
	GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o $(BIN_DIR)/$(BIN_NAME)-darwin-amd64 $(CMD)
	@echo "Built $(BIN_DIR)/$(BIN_NAME)-darwin-amd64 (v$(VERSION))"

## build-all: Build for all platforms
build-all: build-linux build-linux-arm64 build-darwin build-darwin-amd64
	@echo "All platform builds complete."

# ── Test & Quality ────────────────────────────────────────────────────────────

## test: Run all unit tests with race detector
test:
	go test -race -count=1 ./...

## test-verbose: Run tests with verbose output
test-verbose:
	go test -race -count=1 -v ./...

## vet: Run go vet
vet:
	go vet ./...

## fmt: Check formatting (does not modify files; exits non-zero if changes needed)
fmt:
	@unformatted=$$(gofmt -l .); \
	if [ -n "$$unformatted" ]; then \
		echo "The following files need gofmt:"; \
		echo "$$unformatted"; \
		exit 1; \
	else \
		echo "All files are properly formatted."; \
	fi

## fmt-fix: Apply gofmt to all Go source files
fmt-fix:
	gofmt -w .

## check: Run vet + fmt + test
check: vet fmt test

# ── Install ───────────────────────────────────────────────────────────────────
# Installs to the SDP log_feeder directory on a Linux system.
# Requires: INSTANCE variable (SDP instance number, e.g. make install INSTANCE=1)

SDP_SITE_DIR := /p4/common/site/log_feeder
SYSTEMD_DIR  := /etc/systemd/system

## install: Install p4lf binary, config example, and systemd unit (requires root or sudo)
install: build-linux
	@if [ -z "$(INSTANCE)" ]; then \
		echo "Error: INSTANCE is required. Usage: make install INSTANCE=1"; \
		exit 1; \
	fi
	@echo "Installing p4lf to $(SDP_SITE_DIR)..."
	install -d $(SDP_SITE_DIR)
	install -m 0755 $(BIN_DIR)/$(BIN_NAME)-linux-amd64 $(SDP_SITE_DIR)/$(BIN_NAME)
	@if [ ! -f $(SDP_SITE_DIR)/p4lf.cfg ]; then \
		install -m 0640 p4lf.cfg.example $(SDP_SITE_DIR)/p4lf.cfg; \
		echo "  Installed default config to $(SDP_SITE_DIR)/p4lf.cfg — please review and edit."; \
	else \
		echo "  Config $(SDP_SITE_DIR)/p4lf.cfg already exists; not overwriting."; \
	fi
	@echo "Installing systemd unit..."
	install -m 0644 p4lf.service $(SYSTEMD_DIR)/p4lf.service
	systemctl daemon-reload
	@echo ""
	@echo "Installation complete. Next steps:"
	@echo "  1. Edit $(SDP_SITE_DIR)/p4lf.cfg"
	@echo "  2. systemctl enable p4lf"
	@echo "  3. systemctl start p4lf"
	@echo "  4. systemctl status p4lf"

# ── Release ───────────────────────────────────────────────────────────────────

## release: Build all platforms and create dist/ tarballs
release: build-all
	@mkdir -p $(DIST_DIR)
	@echo "Creating release archives for v$(VERSION) (P4CL=$(P4CL))..."
	@for platform in linux-amd64 linux-arm64 darwin-arm64 darwin-amd64; do \
		archive=$(DIST_DIR)/$(BIN_NAME)-$(VERSION)-$$platform.tar.gz; \
		tar -czf $$archive \
			-C $(BIN_DIR) $(BIN_NAME)-$$platform \
			p4lf.cfg.example \
			p4lf.service \
			README.md; \
		echo "  Created $$archive"; \
	done
	@echo "Release archives written to $(DIST_DIR)/"

# ── Clean ─────────────────────────────────────────────────────────────────────

## clean: Remove build and release artifacts
clean:
	rm -rf $(BIN_DIR) $(DIST_DIR)
	@echo "Cleaned."

# ── Help ──────────────────────────────────────────────────────────────────────

## help: Show this help message
help:
	@echo "p4lf Makefile — available targets:"
	@echo ""
	@grep -E '^## ' $(MAKEFILE_LIST) | sed 's/## /  /'
	@echo ""
	@echo "Variables:"
	@echo "  VERSION=$(VERSION)  (override: make build VERSION=1.2.3)"
	@echo "  INSTANCE=<n>        (required for: make install)"
