## Copyright 2022 schukai GmbH. All rights reserved.
## Use of this source code is governed by a AGPL-3.0
## license that can be found in the LICENSE file.

PROJECT_ROOT:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
THIS_MAKEFILE:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
THIS_MAKEFILE_PATH:=$(PROJECT_ROOT)$(THIS_MAKEFILE) 

# @see .PHONY https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html#Phony-Targets
.DEFAULT_GOAL := help

.PHONY: print
## Print Path	
print:
	@echo "THIS_MAKEFILE:      $(THIS_MAKEFILE)"
	@echo "THIS_MAKEFILE_PATH: $(THIS_MAKEFILE_PATH)"
	@echo "PROJECT_ROOT:       $(PROJECT_ROOT)"

# Add a comment to the public targets so that it appears
# in this help Use two # characters for a help comment
.PHONY: help
help:
	@printf "${COMMENT}Usage:${RESET}\n"
	@printf " make [target] [arg=\"val\"...]\n\n"
	@printf "${COMMENT}Available targets:${RESET}\n"
	@awk '/^[a-zA-Z\-\\_0-9\.@]+:/ { \
		helpMessage = match(lastLine, /^## (.*)/); \
		if (helpMessage) { \
			helpCommand = substr($$1, 0, index($$1, ":")); \
			helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \
			printf " ${INFO}%-22s${RESET} %s\n", helpCommand, helpMessage; \
		} \
	} \
	{ lastLine = $$0 }' $(MAKEFILE_LIST)
	@printf "\n${COMMENT}Available arguments:${RESET}\n\n"
	@awk '/^(([a-zA-Z\-\\_0-9\.@]+)\s[?:]?=)/ { \
		helpMessage = match(lastLine, /^## (.*)/); \
		if (helpMessage) { \
			helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \
			printf " ${INFO}%-22s${RESET} %s (Default: %s)\n", $$1, helpMessage, $$3; \
		} \
	} \
	{ lastLine = $$0 }' $(MAKEFILE_LIST)


## run tests
test:
	echo "Running tests"
	go test -cover -v ./...

## run tests with fuzzing
test-fuzz:
	echo "Running fuzz tests"
	go test -v -fuzztime=30s -fuzz=Fuzz ./...

#### VERSION
BIN_DIR ?= $(shell echo $$HOME)/.local/bin/
VERSION_NAME 	     := version
EXECUTABLES = $(EXECUTABLES:-) $(VERSION_NAME)
VERSION_BIN_PATH := $(BIN_DIR)$(VERSION_NAME)

VERSION_BIN := $(shell command -v $(VERSION_NAME) 2> /dev/null)

ifndef VERSION_BIN
    $(shell curl -o $(VERSION_BIN_PATH) http://download.schukai.com/tools/version/version-$(shell uname -s | tr [:upper:] [:lower:])-$(shell echo `uname -m | sed s/aarch64/arm64/ | sed s/x86_64/amd64/`))
    $(shell chmod +x $(VERSION_BIN_PATH))
endif

GIT_CHGLOG_BIN := $(shell command -v git-chglog 2> /dev/null)

ifeq ($(GIT_CHGLOG_BIN),)
    $(shell go install github.com/git-chglog/git-chglog/cmd/git-chglog@latest)
endif     
     
RELEASE_FILE ?= $(PROJECT_ROOT)release.json
CHANGELOG_FILE ?= $(PROJECT_ROOT)CHANGELOG.md
 
ifeq ("$(wildcard $(RELEASE_FILE))","")
  $(shell echo '{"version":"0.1.0"}' > $(RELEASE_FILE))
endif

PROJECT_VERSION ?= $(shell cat $(RELEASE_FILE) | jq -r .version)
PROJECT_BUILD_DATE ?= $(shell $(VERSION_BIN) date)

.PHONY: next-patch-version
next-patch-version: check-clean-repo
	echo "Creating next version"
	$(VERSION_BIN) patch --path $(RELEASE_FILE) --selector "version"
	git add $(RELEASE_FILE) && git commit -m "Bump version to $$(cat $(RELEASE_FILE) | jq -r .version)"

.PHONY: next-minor-version
next-minor-version: check-clean-repo
	echo  "Creating next minor version"
	$(VERSION_BIN) minor --path $(RELEASE_FILE) --selector "version"
	git add $(RELEASE_FILE) && git commit -m "Bump version to $$( cat $(RELEASE_FILE) | jq -r .version)"

.PHONY: next-major-version
next-major-version: check-clean-repo
	echo "Creating next minor version"
	$(VERSION_BIN) major --path $(RELEASE_FILE) --selector "version"
	git add $(RELEASE_FILE) && git commit -m "Bump version to $$(cat $(RELEASE_FILE) | jq -r .version)"

.PHONY: check-clean-repo
check-clean-repo:
	git diff-index --quiet HEAD || (echo "There are uncommitted changes after running make. Please commit or stash them before running make."; exit 1)
	
## tag repository with next patch version
tag-patch-version: next-patch-version 
	echo "Tagging patch version"
	$(eval PROJECT_VERSION := $(shell cat $(RELEASE_FILE) | jq -r .version))
	git-chglog --next-tag v$(PROJECT_VERSION) -o $(CHANGELOG_FILE)
	git add $(CHANGELOG_FILE) && git commit -m "Update changelog"
	git tag -a v$(PROJECT_VERSION) -m "Version $(PROJECT_VERSION)"

## tag repository with next minor version
tag-minor-version: next-minor-version 
	echo "Tagging minor version"
	$(eval PROJECT_VERSION := $(shell cat $(RELEASE_FILE) | jq -r .version))
	git-chglog --next-tag v$(PROJECT_VERSION) -o $(CHANGELOG_FILE)
	git add $(CHANGELOG_FILE) && git commit -m "Update changelog"
	git tag -a v$(PROJECT_VERSION) -m "Version $(PROJECT_VERSION)"

## tag repository with next major version
tag-major-version: next-major-version 
	echo "Tagging major version"
	$(eval PROJECT_VERSION := $(shell cat $(RELEASE_FILE) | jq -r .version))
	git-chglog --next-tag v$(PROJECT_VERSION) -o $(CHANGELOG_FILE)
	git add $(CHANGELOG_FILE) && git commit -m "Update changelog"
	git tag -a v$(PROJECT_VERSION) -m "Version $(PROJECT_VERSION)"

GO_MOD_FILE := $(SOURCE_PATH)go.mod

ifeq ($(shell test -e $(GO_MOD_FILE) && echo -n yes),yes)
    GO_CURRENT_MODULE := $(shell cat $(GO_MOD_FILE) | head -n1 | cut -d" " -f2)
	# go install github.com/google/go-licenses@latest
	EXECUTABLES = $(EXECUTABLES:-) go-licenses;    
endif

.PHONY: fetch-licenses
## Fetch licenses for all modules
fetch-licenses:
	go-licenses save $(GO_CURRENT_MODULE) --force --save_path $(PROJECT_ROOT)licenses/ ; cd -

# https://spdx.github.io/spdx-spec/v2.3/SPDX-license-list/
ADDLICENSE_BIN ?= addlicense
ifeq ($(shell command -v $(ADDLICENSE_BIN) 2> /dev/null),)
	$(shell go install github.com/google/addlicense@latest)
	EXECUTABLES = $(EXECUTABLES:-) $(ADDLICENSE_BIN);
endif

.PHONY: add-licenses
## Add license headers to all go files
add-licenses:
	addlicense -c "schukai GmbH" -s -l "AGPL-3.0-or-later" ./*.go