GOPATH_BIN := $(shell go env GOPATH 2>/dev/null)/bin
PROTOC_BIN := $(HOME)/.cache/protoc/bin
export PATH := $(PROTOC_BIN):$(GOPATH_BIN):$(PATH)

SHELL := /bin/bash

MODULE := git.binarycollective.de/binary/binary-transfer-cli
BINARY := btx
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
LDFLAGS := -s -w -X git.binarycollective.de/binary/binary-transfer-cli/internal/cli.version=$(VERSION)

PROTOC_VERSION ?= 35.1
PROTOC_GEN_GO_VERSION ?= v1.36.11
PROTOC_GEN_GO_GRPC_VERSION ?= v1.6.2

PROTO_STAGE := .proto-stage
PROTO_SOURCES := $(shell find protos -name '*.proto' 2>/dev/null)
GEN_STAMP := gen/.stamp
PROTO_FILES := \
	$(PROTO_STAGE)/common/v1/common.proto \
	$(PROTO_STAGE)/file/v1/file.proto \
	$(PROTO_STAGE)/project/v1/project.proto \
	$(PROTO_STAGE)/settings/v1/settings.proto \
	$(PROTO_STAGE)/share/v1/share.proto \
	$(PROTO_STAGE)/transfer/v1/transfer.proto \
	$(PROTO_STAGE)/user/v1/user.proto \
	$(PROTO_STAGE)/workspace/v1/workspace.proto

GOOS_LIST ?= linux darwin windows
GOARCH_LIST ?= amd64 arm64

.PHONY: all btx build install proto-go prepare-protos run-protoc generate tidy test lint clean cross modzip

all: generate tidy build

btx: build

build: generate
	go build -ldflags "$(LDFLAGS)" -o $(BINARY) ./cmd/btx

install: generate
	go install -ldflags "$(LDFLAGS)" ./cmd/btx

proto-go: generate

prepare-protos:
	@test -d protos || (echo "protos submodule missing: git submodule update --init --recursive"; exit 1)
	rm -rf $(PROTO_STAGE)
	cp -R protos $(PROTO_STAGE)
	@find $(PROTO_STAGE) -name '*.proto' -print0 | while IFS= read -r -d '' f; do \
		sed -i.bak 's|github.com/fronbasal/binary-transfer-api/gen/|git.binarycollective.de/binary/binary-transfer-cli/gen/|g' "$$f" && rm -f "$$f.bak"; \
	done

run-protoc: prepare-protos
	@command -v protoc >/dev/null || (echo "protoc required (version $(PROTOC_VERSION))"; exit 1)
	@protoc_ver=$$(protoc --version | awk '{print $$2}'); \
	if [ "$$protoc_ver" != "$(PROTOC_VERSION)" ]; then \
		echo "protoc $(PROTOC_VERSION) required, got $$protoc_ver"; \
		exit 1; \
	fi
	@export PATH="$$(go env GOPATH)/bin:$$PATH"; \
	command -v protoc-gen-go >/dev/null || (echo "protoc-gen-go required: go install google.golang.org/protobuf/cmd/protoc-gen-go@$(PROTOC_GEN_GO_VERSION)"; exit 1); \
	command -v protoc-gen-go-grpc >/dev/null || (echo "protoc-gen-go-grpc required: go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@$(PROTOC_GEN_GO_GRPC_VERSION)"; exit 1); \
	mkdir -p gen; \
	protoc -I $(PROTO_STAGE) \
		--go_out=gen --go_opt=paths=source_relative \
		--go-grpc_out=gen --go-grpc_opt=paths=source_relative \
		$(PROTO_FILES)

$(GEN_STAMP): $(PROTO_SOURCES) Makefile
	@$(MAKE) run-protoc
	@touch $@

generate: $(GEN_STAMP)

tidy:
	go mod tidy

test: generate
	go test ./...

lint: generate
	go vet ./...

clean:
	rm -rf $(BINARY) dist/ $(PROTO_STAGE) gen/

cross: generate tidy
	@mkdir -p dist
	@for goos in $(GOOS_LIST); do \
		for goarch in $(GOARCH_LIST); do \
			if [ "$$goos" = "darwin" ] && [ "$$goarch" = "amd64" ]; then continue; fi; \
			out=dist/$(BINARY)-$$goos-$$goarch; \
			if [ "$$goos" = "windows" ]; then out=$$out.exe; fi; \
			echo "building $$out"; \
			GOOS=$$goos GOARCH=$$goarch CGO_ENABLED=0 go build -ldflags "$(LDFLAGS)" -o $$out ./cmd/btx; \
		done; \
	done

modzip: generate
	@test -n "$(VERSION)" || (echo "VERSION required, e.g. make modzip VERSION=v0.1.0"; exit 1)
	@mkdir -p dist
	@tmp=$$(mktemp /tmp/binary-transfer-cli.XXXXXX.zip); \
	go run ./scripts/modzip "$(VERSION)" "$$tmp"; \
	mv "$$tmp" "dist/binary-transfer-cli@$(VERSION).zip"
