# Call `make V=1` in order to print commands verbosely.
ifeq ($(V),1)
    Q =
else
    Q = @
endif

SHELL = /usr/bin/env bash -eo pipefail

# Host information
OS   := $(shell uname)
ARCH := $(shell uname -m)

# Directories
SOURCE_DIR       := $(abspath $(dir $(lastword ${MAKEFILE_LIST})))
BUILD_DIR        := ${SOURCE_DIR}/build
TOOLS_DIR        := ${SOURCE_DIR}/tools

VER:='gitlab.com/gitlab-org/spamcheck=v0.0.1'
GIT:='gitlab.com/gitlab-org/spamcheck.gitCommit=' #$(shell git rev-parse --short HEAD)'
BUILD_TAG:='gitlab.com/gitlab-org/spamcheck.buildTag=42'
BUILD_TS:='gitlab.com/gitlab-org/spamcheck.buildTimestamp=$(shell date -u +"%Y-%m-%dT%H:%M:%SZ")'
JAEGER_BUILD_TAGS := tracer_static tracer_static_jaeger

# Tools
PROTO_DIR         := ${SOURCE_DIR}/api/v1
RUBY_PROTO_DIR    := ${SOURCE_DIR}/ruby/api/v1
PROTOC_DIR        := ${TOOLS_DIR}/protoc
PROTOC            := ${PROTOC_DIR}/bin/protoc
DOCS_DIR          := ${SOURCE_DIR}/docs/api/v1

# Tools options

# Dependency versions
PROTOC_VERSION             ?= 3.14.0
PROTOC_GEN_GO_VERSION      ?= 1.25.0
PROTOC_GEN_GRPC_VERSION    ?= 1.0.1
PROTOC_GEN_GRPC_GW_VERSION ?= 2.1.0

# Dependency downloads
ifeq (${OS},Darwin)
    PROTOC_URL            ?= https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-osx-x86_64.zip
    PROTOC_HASH           ?= 699ceee7ef0988ecf72bf1c146dee5d9d89351a19d4093d30ebea3c04008bb8c
else ifeq (${OS},Linux)
    PROTOC_URL            ?= https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-x86_64.zip
    PROTOC_HASH           ?= a2900100ef9cda17d9c0bbf6a3c3592e809f9842f2d9f0d50e3fba7f3fc864f0
endif

.protoc-gen-ruby:
	@echo [!] installing bundler and gems
	@gem install bundler
	@bundle install

# https://github.com/grpc-ecosystem/grpc-gateway#installation
.install-tools:
	@echo [!] Installing tools from tools.go
	@go get google.golang.org/protobuf/cmd/protoc-gen-go@v${PROTOC_GEN_GO_VERSION}
	@go get google.golang.org/grpc/cmd/protoc-gen-go-grpc@v${PROTOC_GEN_GRPC_VERSION}
	@go get github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@v${PROTOC_GEN_GRPC_GW_VERSION}
	@go get github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@v${PROTOC_GEN_GRPC_GW_VERSION}
	@cat tools.go | grep _ | awk -F'"' '{print $$2}' | xargs -tI % go install %

${PROTOC_DIR}/protoc.zip: 
	${Q}if [ -z "${PROTOC_URL}" ]; then echo "Cannot generate protos on unsupported platform ${OS}" && exit 1; fi
	@echo [!] ${PROTOC_DIR}/protoc.zip not found, downloading ${PROTOC_URL}
	curl -o protoc.tmp --show-error -L ${PROTOC_URL}
	rm -rf ${PROTOC_DIR}
	mkdir -p ${PROTOC_DIR}
	mv protoc.tmp ${PROTOC_DIR}/protoc.zip
	ls -lah ${PROTOC_DIR}

${PROTOC}: ${PROTOC_DIR}/protoc.zip 
	${Q}if printf '${PROTOC_HASH}  ${PROTOC_DIR}/protoc.zip' | sha256sum -c -	;\
	then										 \
	echo [!] ${PROTOC_DIR}/protoc.zip matches pinned ${OS} hash ${PROTOC_HASH} 	;\
	unzip -q -o ${PROTOC_DIR}/protoc.zip -d ${PROTOC_DIR}				;\
	else										 \
	@echo [!] protoc.zip does not match ${PROTOC_HASH}, no *.pb.* files generated.	;\
	@echo [!] remove the ${PROTOC_DIR}/protoc.zip or change the pinned hash.	;\
	exit 1										;\
	fi

proto: ${PROTOC} .protoc-gen-ruby .install-tools
	@echo [!] removing ${PROTO_DIR}/*.pb.go
	@rm -Rf ${PROTO_DIR}/*.pb.go
	@echo [!] compiling PB files ...
	@echo [!] PROTO_DIR=${PROTO_DIR}
	@echo [!] PROTOC_DIR=${PROTOC_DIR}
	@echo [!] DOCS_DIR=${DOCS_DIR}

	mkdir -p ${DOCS_DIR}

	# Generate Go protobuf files
	@${PROTOC_DIR}/bin/protoc -I${PROTOC_DIR}/include				 	\
        -I$$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis     	\
        -I$$GOPATH/pkg/mod/github.com/grpc-ecosystem/grpc-gateway/v2@v2.1.0/third_party/googleapis	\
        --go_out=${PROTO_DIR}               						 	\
        --go-grpc_out=${PROTO_DIR}          						 	\
        --grpc-gateway_out=${PROTO_DIR}       					 	 	\
        --openapiv2_out=${DOCS_DIR}     							 	\
        --proto_path=${PROTO_DIR}             						 	\
        ${PROTO_DIR}/spamcheck.proto	

	# Generate Ruby protobuf files
	@bundle exec ruby _support/generate-proto-ruby

	@echo [!] go_out=${PROTO_DIR}
	@echo [!] go-grpc_out=${PROTO_DIR}
	@echo [!] go-grpc-gateway_out=${PROTO_DIR}
	@echo [!] openapiv2_out=${DOCS_DIR}
	@echo [!] ruby-proto-out=${RUBY_PROTO_DIR}
	ls -lah ${PROTO_DIR}

build: proto
	@echo [!] building ...
	@go build -ldflags="-X ${VER} -X ${GIT} -X ${BUILD_TAG} -X ${BUILD_TS}" -tags "${JAEGER_BUILD_TAGS}"

gem: proto
	@bundle exec ruby _support/publish-gem

test: 
	@echo testing ...
	@go test -failfast ./...

run: proto
	@go run -ldflags="-X ${VER} -X ${GIT} -X ${BUILD_TAG} -X ${BUILD_TS}" -tags "${JAEGER_BUILD_TAGS}" main.go

.PHONY: proto build test run
