#!/usr/bin/make -f
SHELL = bash

VERSION ?= $(shell git describe --tags --match "v*" --abbrev=8 --dirty --always)
PROTOC_VERSION ?= 27.2
PROTOC_GEN_GO_VERSION ?= $(shell go list -f '{{.Version}}' -m google.golang.org/protobuf)
PROTOC_OS_VERSION=osx-x86_64
ifeq ($(shell uname), Linux)
	PROTOC_OS_VERSION=linux-x86_64
endif

BIN = bin
PROTOBUF_DIR ?= $(abspath $(BIN))/protobuf
PROTOC_DIR ?= $(PROTOBUF_DIR)/protoc-v$(PROTOC_VERSION)
PROTOC_GEN_GO_DIR ?= $(PROTOBUF_DIR)/protoc-gen-go-$(PROTOC_GEN_GO_VERSION)

.PHONY: dep fmts fumpt imports protoc test lint version help $(BIN)/protogen protoc-test

# Pull go dependencies
dep:
	@printf "⇒ Tidy requirements : "
	CGO_ENABLED=0 \
	go mod tidy -v && echo OK
	@printf "⇒ Download requirements: "
	CGO_ENABLED=0 \
	go mod download && echo OK
	@printf "⇒ Install test requirements: "
	CGO_ENABLED=0 \
	go test ./... && echo OK

# Run all code formatters
fmts: fumpt imports

# Reformat imports
imports:
	@echo "⇒ Processing goimports check"
	@for f in `find . -type f -name '*.go' -not -name '*.pb.go' -prune`; do \
		goimports -w $$f; \
	done

# Run gofumpt
fumpt:
	@echo "⇒ Processing gofumpt check"
	@gofumpt -l -w .

# Install protoc
protoc-install:
	@rm -rf $(PROTOBUF_DIR)
	@mkdir -p $(PROTOBUF_DIR)
	@echo "⇒ Installing protoc... "
	@wget -q -O $(PROTOBUF_DIR)/protoc-$(PROTOC_VERSION).zip 'https://github.com/protocolbuffers/protobuf/releases/download/v$(PROTOC_VERSION)/protoc-$(PROTOC_VERSION)-$(PROTOC_OS_VERSION).zip'
	@unzip -q -o $(PROTOBUF_DIR)/protoc-$(PROTOC_VERSION).zip -d $(PROTOC_DIR)
	@rm $(PROTOBUF_DIR)/protoc-$(PROTOC_VERSION).zip
	@echo "⇒ Installing protoc-gen-go..."
	@GOBIN=$(PROTOC_GEN_GO_DIR) go install -v google.golang.org/protobuf/...@$(PROTOC_GEN_GO_VERSION)


# Regenerate code for proto files
protoc:
	@if [ ! -d "$(PROTOC_DIR)" ] || [ ! -d "$(PROTOC_GEN_GO_DIR)" ]; then \
		make protoc-install; \
	fi
	# Protoc generate
	@for f in `find . -type f -name '*.proto' -not -path './bin/*' -not -path './util/proto/test/*'`; do \
		echo "⇒ Processing $$f "; \
		$(PROTOC_DIR)/bin/protoc \
			--proto_path=.:$(PROTOC_DIR)/include:/usr/local/include \
			--plugin=protoc-gen-go-frostfs=$(abspath ./bin/protogen) \
			--go-frostfs_out=fuzz=true:. \
			--go-frostfs_opt=paths=source_relative \
			--go-grpc_opt=require_unimplemented_servers=false \
			--go-grpc_out=. --go-grpc_opt=paths=source_relative $$f; \
	done

$(BIN)/protogen:
	@go build -v -trimpath \
		-o $(BIN)/protogen \
		./util/protogen

protoc-test: protoc $(BIN)/protogen
	@$(PROTOC_DIR)/bin/protoc \
			--go_out=. --go_opt=paths=source_relative \
			--plugin=protoc-gen-go-frostfs=$(abspath $(BIN)/protogen) \
			--go-frostfs_opt=Mutil/proto/test/test.proto=git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/proto/test/custom \
			--go-frostfs_opt=module=git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 \
			--go-frostfs_out=. --go-frostfs_opt=paths=import \
			./util/proto/test/test.proto

# Run Unit Test with go test
test: GOFLAGS ?= "-count=1"
test:
	@echo "⇒ Running go test"
	@GOFLAGS="$(GOFLAGS)" go test ./...

# Run linters
lint:
	@golangci-lint run

# Print version
version:
	@echo $(VERSION)

# Show this help prompt
help:
	@echo '  Usage:'
	@echo ''
	@echo '    make <target>'
	@echo ''
	@echo '  Targets:'
	@echo ''
	@awk '/^#/{ comment = substr($$0,3) } comment && /^[a-zA-Z][a-zA-Z0-9_-]+ ?:/{ print "   ", $$1, comment }' $(MAKEFILE_LIST) | column -t -s ':' | grep -v 'IGNORE' | sort -u