.PHONY: help init setup build run test test-race lint lint-fix security docs clean

include tools.versions

# ── Variables ──────────────────────────────────────────────────────────────────
BINARY_NAME  := app
BINARY_PATH  := ./bin/$(BINARY_NAME)
CMD_PATH     := ./cmd/app

# ── Default target ─────────────────────────────────────────────────────────────
help: ## Show this help message
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' Makefile | \
		awk 'BEGIN {FS = ":.*?## "}; {printf "  \033[36m%-16s\033[0m %s\n", $$1, $$2}' | sort

# ── First-time setup ───────────────────────────────────────────────────────────
init: ## First-time project init: fetch deps, configure git hooks
	go env -w GOPRIVATE=gitea.djmil.dev
	go mod tidy
	$(MAKE) setup
	@echo "Done! Run 'make build' to verify."

setup: ## Configure git to use .githooks directory
	git config core.hooksPath .githooks
	chmod +x .githooks/*
	@echo "Git hooks configured: .githooks/"

# ── Development tools ──────────────────────────────────────────────────────────
tools: ## Install tool binaries to GOPATH/bin (versions from tools.versions)
	@echo "Installing tools..."
	go install github.com/go-delve/delve/cmd/dlv@$(DELVE_VERSION)
	go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)
	go install github.com/securego/gosec/v2/cmd/gosec@$(GOSEC_VERSION)
	go install golang.org/x/vuln/cmd/govulncheck@$(GOVULNCHECK_VERSION)
	go install golang.org/x/pkgsite/cmd/pkgsite@$(PKGSITE_VERSION)

# ── Build ──────────────────────────────────────────────────────────────────────
build: ## Compile the binary to ./bin/
	go build -o $(BINARY_PATH) $(CMD_PATH)

# ── Run ────────────────────────────────────────────────────────────────────────
run: ## Run the application with default flags
	go run $(CMD_PATH)/main.go

# ── Test ───────────────────────────────────────────────────────────────────────
test: ## Run all tests
	go test ./... -cover

test-race: ## Run all tests with race detector
	go test ./... -race -cover

test-verbose: ## Run all tests with verbose output
	go test ./... -race -cover -v

# ── Lint & Security ────────────────────────────────────────────────────────────
lint: ## Run go vet + golangci-lint
	go vet ./...
	go run github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) run ./...

lint-fix: ## Apply go fix + golangci-lint auto-fix
	go fix ./...
	go run github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) run --fix ./...

security: ## Run gosec + govulncheck
	@echo "--- gosec ---"
	go run github.com/securego/gosec/v2/cmd/gosec@$(GOSEC_VERSION) -quiet ./...
	@echo "--- govulncheck ---"
	go run golang.org/x/vuln/cmd/govulncheck@$(GOVULNCHECK_VERSION) ./...

# ── Docs ───────────────────────────────────────────────────────────────────────
docs: ## Serve package documentation locally via pkgsite (http://localhost:8080)
	go run golang.org/x/pkgsite/cmd/pkgsite@$(PKGSITE_VERSION) -open .

# ── Release ────────────────────────────────────────────────────────────────────
release: ## List releases, or tag+push a new one (usage: make release VERSION=v0.1.0)
ifdef VERSION
	@echo "$(VERSION)" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+$$' || \
		(echo "VERSION must be semver: v0.1.0"; exit 1)
	@git diff --quiet && git diff --cached --quiet || \
		(echo "Uncommitted changes — commit first"; exit 1)
	@git tag -l | grep -q "^$(VERSION)$$" && \
		(echo "Tag $(VERSION) already exists"; exit 1) || true
	$(MAKE) test-race
	$(MAKE) lint
	$(MAKE) security
	@MSG=$$(mktemp); \
	LAST=$$(git describe --tags --abbrev=0 2>/dev/null); \
	echo "$(VERSION)" > $$MSG; \
	echo "" >> $$MSG; \
	if [ -n "$$LAST" ]; then \
		echo "Changes since $$LAST:" >> $$MSG; \
		git log $$LAST..HEAD --oneline >> $$MSG; \
	else \
		git log --oneline >> $$MSG; \
	fi; \
	git tag -a -e -F $$MSG $(VERSION); \
	rm -f $$MSG
	git push origin $(VERSION)
else
	@echo "Released versions:"
	@git tag -l --sort=-version:refname | grep -E '^v[0-9]' || echo "  (none yet)"
endif

# ── Cleanup ────────────────────────────────────────────────────────────────────
clean: ## Remove build artifacts
	rm -rf ./bin
