# ============================================================================
# reg — Docker Registry Client
# Makefile
# ============================================================================

BINARY         := reg
DEBUG_BINARY   := reg-debug
GO_MIN_VERSION := 1.21
PREFIX         := /usr/local
BINDIR         := $(PREFIX)/bin

.PHONY: all deps build static debug check install uninstall clean help

# Цель по умолчанию — динамическая сборка (cgo по умолчанию, если есть gcc).
all: build

# Синхронизация go.mod и go.sum (идемпотентно, безопасно для повторных
# запусков). go mod tidy добавляет недостающие записи в go.sum и при
# необходимости подтягивает/удаляет транзитивные зависимости в go.mod.
# Работает и как замена «go mod download» — после него go build
# гарантированно проходит проверку missing go.sum entry.
deps:
	go mod tidy

# Динамическая сборка (зависит от системной glibc, как обычный go build).
build: deps
	go build -v -trimpath -ldflags="-s -w" -o $(BINARY) .

# Статическая сборка (без cgo, без зависимости от системной glibc).
static: deps
	CGO_ENABLED=0 go build -v -trimpath -ldflags="-s -w" -o $(BINARY) .

# Отладочная сборка: без оптимизаций и инлайнинга, с DWARF-символами.
# Предназначена для delve (dlv) и pprof. Не перезаписывает $(BINARY).
debug: deps
	CGO_ENABLED=0 go build -v -gcflags="all=-N -l" -o $(DEBUG_BINARY) .

# Проверка установленной версии Go.
check:
	@command -v go >/dev/null 2>&1 || { echo "error: go not found in PATH"; exit 1; }
	@GOVER=$$(go env GOVERSION 2>/dev/null | sed 's/^go//'); \
	if [ -z "$$GOVER" ]; then \
	    echo "error: cannot determine Go version"; exit 1; \
	fi; \
	echo "Detected Go version: $$GOVER"; \
	REQ="$(GO_MIN_VERSION)"; \
	MAJ=$$(echo "$$GOVER" | cut -d. -f1); \
	MIN=$$(echo "$$GOVER" | cut -d. -f2); \
	REQ_MAJ=$$(echo "$$REQ" | cut -d. -f1); \
	REQ_MIN=$$(echo "$$REQ" | cut -d. -f2); \
	if [ "$$MAJ" -lt "$$REQ_MAJ" ] || \
	   { [ "$$MAJ" -eq "$$REQ_MAJ" ] && [ "$$MIN" -lt "$$REQ_MIN" ]; }; then \
	    echo "error: Go $$REQ or newer required (found $$GOVER)"; exit 1; \
	fi; \
	echo "OK: Go $$GOVER (>= $$REQ)"

# Установка существующего бинарника в $(BINDIR).
# Соберите перед установкой: make (динамический) или make static (статический).
install:
	@test -f $(BINARY) || { echo "error: $(BINARY) not found, run 'make' or 'make static' first"; exit 1; }
	install -m 0755 -d $(BINDIR)
	install -m 0755 $(BINARY) $(BINDIR)/$(BINARY)

# Удаление бинарника из $(BINDIR).
uninstall:
	rm -f $(BINDIR)/$(BINARY)

# Удаление локальных бинарников (обычного и отладочного).
clean:
	rm -f $(BINARY) $(DEBUG_BINARY)

help:
	@echo "make           — динамическая сборка (./reg), с синхронизацией go.mod/go.sum"
	@echo "make static    — статическая сборка (CGO_ENABLED=0)"
	@echo "make debug     — отладочная сборка (./reg-debug, для dlv)"
	@echo "make deps      — синхронизировать go.mod и go.sum (go mod tidy)"
	@echo "make check     — проверить версию Go (>= $(GO_MIN_VERSION))"
	@echo "make install   — установить $(BINARY) в $(BINDIR)"
	@echo "make uninstall — удалить $(BINARY) из $(BINDIR)"
	@echo "make clean     — удалить локальные $(BINARY) и $(DEBUG_BINARY)"
