# <<project_name>> — build & container automation (pure Make, no CI).
#
#   make help          list targets
#   make build         compile the binary
#   make run           build then run
#   make test          go test
#   make fmt           format (goimports + gofumpt + oxfmt)
#   make lint          golangci-lint (falls back to go vet)
#   make check         fmt-check + lint + test (local verification)
#   make clean         remove build artifacts
#   make docker-build  build the container image
#   make docker-run    run the built image

PROJECT_NAME := <<project_name>>
PROJECT_ROOT := $(abspath .)
DIST_DIR     := dist
BINARY       := $(DIST_DIR)/$(PROJECT_NAME)

VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")

GO_FILES := $(shell find . -name '*.go' -not -path './vendor/*' -not -name '*.pb.go' 2>/dev/null)

HAS_OXFMT     := $(shell command -v oxfmt 2>/dev/null)
HAS_GOFUMPT   := $(shell command -v gofumpt 2>/dev/null)
HAS_GOIMPORTS := $(shell command -v goimports 2>/dev/null)
HAS_GOLANGCI  := $(shell command -v golangci-lint 2>/dev/null)

.DEFAULT_GOAL := help

.PHONY: help build run test fmt fmt-go fmt-oxfmt fmt-check lint check clean docker-build docker-run

help: ## Show this help
	@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort \
		| awk 'BEGIN {FS = ":.*?## "}; {printf "  \033[36m%-14s\033[0m %s\n", $$1, $$2}'

build: ## Build the binary with version injected
	@mkdir -p $(DIST_DIR)
	@CGO_ENABLED=0 go build -ldflags="-s -w -X main.version=$(VERSION)" -o $(BINARY) .

run: build ## Build then run the binary
	@$(BINARY)

test: ## Run tests
	@go test ./... -count=1

fmt: fmt-go fmt-oxfmt ## Format Go + non-Go files

fmt-go:
ifdef HAS_GOIMPORTS
	@echo "$(GO_FILES)" | tr ' ' '\n' | xargs -r -P 4 goimports -w
else
	@echo "goimports not found: go install golang.org/x/tools/cmd/goimports@latest"
endif
ifdef HAS_GOFUMPT
	@echo "$(GO_FILES)" | tr ' ' '\n' | xargs -r -P 4 gofumpt -extra -w
else
	@echo "gofumpt not found: go install mvdan.cc/gofumpt@latest"; gofmt -w $(GO_FILES)
endif

fmt-oxfmt:
ifdef HAS_OXFMT
	@oxfmt --write --no-error-on-unmatched-pattern "$(PROJECT_ROOT)"
else
	@echo "oxfmt not found, skipping non-Go formatting (cargo install oxfmt)"
endif

fmt-check: ## Verify formatting without writing
ifdef HAS_GOFUMPT
	@unformatted=$$(echo "$(GO_FILES)" | tr ' ' '\n' | xargs -r gofumpt -extra -l); \
		if [ -n "$$unformatted" ]; then echo "Unformatted:"; echo "$$unformatted"; exit 1; fi
else
	@test -z "$$(gofmt -l $(GO_FILES))" || { echo "Run 'make fmt'"; exit 1; }
endif
ifdef HAS_OXFMT
	@oxfmt --check --no-error-on-unmatched-pattern "$(PROJECT_ROOT)"
endif

lint: ## Run golangci-lint (falls back to go vet)
ifdef HAS_GOLANGCI
	@golangci-lint run ./...
else
	@echo "golangci-lint not found; running go vet"; go vet ./...
endif

check: fmt-check lint test ## Full local verification
	@echo "All checks passed."

clean: ## Remove build artifacts
	@rm -rf $(DIST_DIR)

docker-build: ## Build the container image
	@docker build --build-arg VERSION=$(VERSION) -t $(PROJECT_NAME):latest .

docker-run: docker-build ## Run the built image
	@docker run --rm<%if port%> -p <<port>>:<<port>><%endif%> $(PROJECT_NAME):latest
