###########################################################################
# Copyright (C) © 2020-2026 IoT.bzh Company
# Contact: https://www.iot.bzh/licensing
#
# This file is part of the redpesk-cli project, the redpesk command line tool.
#
# $RP_BEGIN_LICENSE$
# Commercial License Usage
#  Licensees holding valid commercial IoT.bzh licenses may use this file in
#  accordance with the commercial license agreement provided with the
#  Software or, alternatively, in accordance with the terms contained in
#  a written agreement between you and The IoT.bzh Company. For licensing terms
#  and conditions see https://www.iot.bzh/terms-conditions. For further
#  information use the contact form at https://www.iot.bzh/contact.
#
# GNU General Public License Usage
#  Alternatively, this file may be used under the terms of the GNU General
#  Public license version 3. This license is as published by the Free Software
#  Foundation and appearing in the file LICENSE.GPLv3 included in the packaging
#  of this file. Please review the following information to ensure the GNU
#  General Public License requirements will be met
#  https://www.gnu.org/licenses/gpl-3.0.html.
# $RP_END_LICENSE$
############################################################################

# Application Name
TARGET=rp-cli


# Retrieve git tag/commit to set version & sub-version strings
GIT_DESC := $(shell test -d .git && git describe --always --tags --match "[0-9]*")
VERSION ?= $(firstword $(subst -, ,$(GIT_DESC)))
ifeq (-,$(findstring -,$(GIT_DESC)))
	SUB_VERSION ?= $(subst $(VERSION)-,,$(GIT_DESC))
endif
ifeq ($(VERSION), )
	VERSION := unknown-dev
endif
ifeq ($(SUB_VERSION), )
	SUB_VERSION := $(shell date +'%Y-%m-%d_%H%M%S')
endif

# Configurable variables for installation (default /opt/redepsk/...)
ifeq ($(origin DESTDIR), undefined)
	DESTDIR := /opt/redpesk/cli
endif

# gocover-cobertura packages url
GOCOV_XML_URL=github.com/boumenot/gocover-cobertura@latest

# GO setup
# ifndef GOPATH
# $(error GOPATH is not set, please define GOPATH env variable to a valid path)
# endif
export GOPRIVATE=git.ovh.iot

HOST_GOOS=$(shell go env GOOS)
HOST_GOARCH=$(shell go env GOARCH)
ARCH=$(HOST_GOOS)-$(HOST_GOARCH)
REPOPATH=git.ovh.iot/redpesk/redpesk-infra/redpesk-cli

EXT=
ifeq ($(HOST_GOOS), windows)
	EXT=.exe
endif

mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
ROOT_SRCDIR := $(patsubst %/,%,$(dir $(mkfile_path)))
LOCAL_BINDIR := $(ROOT_SRCDIR)/bin
PACKAGE_DIR := $(ROOT_SRCDIR)/package

# Check Go version
GOVERSION := $(shell go version |grep -o '[0-9\.]*'|head -n 1)
GOVERMAJ := $(shell echo $(GOVERSION) |cut -f1 -d.)
GOVERMIN := $(shell echo $(GOVERSION) |cut -f2 -d.)
CHECKGOVER := $(shell [ $(GOVERMAJ) -gt 1 -o \( $(GOVERMAJ) -eq 1 -a $(GOVERMIN) -ge 23 \) ] && echo true)
CHECKERRMSG := "ERROR: Go version 1.23.0 or higher is requested (current detected version: $(GOVERSION))."

GO_BUILD_FLAGS ?=
ifeq ($(VENDOR), 1)
	GO_BUILD_FLAGS+=-mod=vendor
endif

# Get the current go path
MY_GO_PATH := $(shell go env get GOPATH | xargs)

# Verbose mode -
#  make ... v=0   (or make ... V=0)	=> no verbose
#  make ... v=1   (or make ... V=1)	=> verbose level 1 (default)
#  make ... v=2   (or make ... V=2) => extra verbose
VERBOSE_OPT := -v
ifneq (,$(filter "command line", "$(origin V)" "$(origin v)"))
	ifneq ($(filter 0,$(v) $(V)),)
		VERBOSE_OPT :=
	endif
	ifneq ($(filter 2,$(v) $(V)),)
		VERBOSE_OPT := -v -x
	endif
endif

# go race mode
RACE_OPT:=
ifneq (,$(filter "command line", "$(origin race)" "$(origin RACE)"))
 	RACE_OPT := -race
endif


# Release or Debug mode
ifeq ($(filter 1,$(RELEASE) $(REL)),)
	GO_LDFLAGS=
	# disable compiler optimizations and inlining
	GO_GCFLAGS=-N -l
	BUILD_MODE="development"
else
	# optimized code without debug info
	GO_BUILD_FLAGS+=-buildmode=pie
	GO_LDFLAGS=-s -w
	GO_GCFLAGS=
	BUILD_MODE="production"
endif

# Build Package name (model: <target>_<arch>-<version>.<nb_commit_from_last_tag>.zip)
ifeq (-g,$(findstring -g,$(GIT_DESC)))
	NB_COMMIT=$(firstword $(subst -, ,$(SUB_VERSION)))
else
	NB_COMMIT=0
endif
PACKAGE_ZIPFILE := $(TARGET)_$(ARCH)-$(VERSION).$(NB_COMMIT).zip

.PHONY: all
all: gomod build

.PHONY: deps gomod
deps gomod: checkgover
	go get

.PHONY: tidy
tidy: checkgover
	go mod tidy

.PHONY: build
build: checkgover
	@echo "### Build $(TARGET) (version $(VERSION), subversion $(SUB_VERSION) - Build mode: $(BUILD_MODE))";
	@cd $(ROOT_SRCDIR); $(BUILD_ENV_FLAGS) go build $(VERBOSE_OPT) -o $(LOCAL_BINDIR)/$(TARGET)$(EXT) $(GO_BUILD_FLAGS) -ldflags "$(GO_LDFLAGS) -X $(REPOPATH)/cmd.AppVersion=$(VERSION) -X $(REPOPATH)/cmd.AppSubVersion=$(SUB_VERSION) -X $(REPOPATH)/cmd.AppBuildDateYear=$(shell date "+%Y") -X $(REPOPATH)/cmd.BuildMode=$(BUILD_MODE)" -gcflags "$(GO_GCFLAGS)" .

.PHONY: test
test: checktools
ifndef name
	go test ./... $(VERBOSE_OPT) $(RACE_OPT) -timeout 200s -cover -count=1
else
	go test ./... $(VERBOSE_OPT) $(RACE_OPT) -timeout 100s -cover -count=1 -run $(name)
endif

.PHONY: test_ci
test_ci: checktools
	go clean -testcache
	go test ./... $(VERBOSE_OPT) -timeout 300s -coverprofile=./test-rp-cli-coverage.out -count 1 -covermode count
	[[ ! -e $(MY_GO_PATH)/bin/gocover-cobertura ]] && { echo "Installing gocover-cobertura..."; pushd ${HOME}; go install ${GOCOV_XML_URL}; popd; } || true
	${MY_GO_PATH}/bin/gocover-cobertura < ./test-rp-cli-coverage.out > ./test-rp-cli-coverage.xml
	go tool cover -html=./test-rp-cli-coverage.out -o ./test-rp-cli-coverage.html

.PHONY: test_irl
test_irl:
	BCK_URL=http://0.0.0.0:8000 go test ./... $(VERBOSE_OPT) -cover -count=1

.PHONY: clean
clean:
	rm -rf $(LOCAL_BINDIR)/* $(ROOT_SRCDIR)/debug $(GOPATH)/pkg/*/$(REPOPATH) $(PACKAGE_DIR)

.PHONY: distclean
distclean: clean
	(cd $(ROOT_SRCDIR) && rm -rf $(LOCAL_BINDIR) ./tools ./vendor ./*.zip)
	 go clean -modcache

.PHONY: scripts
scripts:
	@mkdir -p $(LOCAL_BINDIR) && cp -rf scripts/*.sh scripts/rp-utils $(LOCAL_BINDIR)

.PHONY: release
release:
	RELEASE=1 VENDOR=1 make -f $(ROOT_SRCDIR)/Makefile clean build

.PHONY: modrelease
modrelease:
	RELEASE=1 make -f $(ROOT_SRCDIR)/Makefile clean build

package: clean build
	@mkdir -p $(PACKAGE_DIR)/$(TARGET)
	@cp -a $(LOCAL_BINDIR)/*cli$(EXT) $(PACKAGE_DIR)/$(TARGET)
ifneq ($(GOOS), windows)
	@cp -r $(ROOT_SRCDIR)/conf.d $(ROOT_SRCDIR)/scripts $(PACKAGE_DIR)/$(TARGET)
endif
	cd $(PACKAGE_DIR) && zip -r $(ROOT_SRCDIR)/$(PACKAGE_ZIPFILE) ./$(TARGET)

package/linux:
	@echo "# Build linux amd64..."
	GOOS=linux GOARCH=amd64 RELEASE=1 make -f $(ROOT_SRCDIR)/Makefile package

package/windows:
	@echo "# Build windows amd64..."
	GOOS=windows GOARCH=amd64 RELEASE=1 make -f $(ROOT_SRCDIR)/Makefile package

package/macos:
	@echo "# Build darwin amd64..."
	GOOS=darwin GOARCH=amd64 RELEASE=1 make -f $(ROOT_SRCDIR)/Makefile package

.PHONY: package-all
package-all: package/linux package/windows package/macos
	make -f $(ROOT_SRCDIR)/Makefile clean

.PHONY: install
install:
	@test -e $(LOCAL_BINDIR)/$(TARGET)$(EXT) || { echo -e "Please execute first: make all\n"; exit 1; }
	export DESTDIR=$(DESTDIR) && $(ROOT_SRCDIR)/scripts/install.sh

.PHONY: uninstall
uninstall:
	export DESTDIR=$(DESTDIR) && $(ROOT_SRCDIR)/scripts/install.sh uninstall

.PHONY: cmd-list
cmd-list:
	@rp-cli misc cmd-tree > cmd-tree.txt
	$(ROOT_SRCDIR)/scripts/rework_cmdtree_output.py cmd-tree.txt
	@rm cmd-tree.txt
	@echo "# Please modify the file 'docs/4_command-list.md' with the content of 'cmd-tree-aligned.txt'"

.PHONY:
checkgover:
	@test "$(CHECKGOVER)" = "true" || { echo -e $(CHECKERRMSG); exit 1; }

.PHONY:
checktools:
	@command -v which >/dev/null 2>&1 || { echo -e "Please install missing tool: which\n"; exit 1; }
	@command -v git   >/dev/null 2>&1 || { echo -e "Please install missing tool: git\n"; exit 1; }
	@command -v tar   >/dev/null 2>&1 || { echo -e "Please install missing tool: tar\n"; exit 1; }

.PHONY: help
help:
	@echo "Main supported rules:"
	@echo "  all                (default)"
	@echo "  deps"
	@echo "  build"
	@echo "  release"
	@echo "  package"
	@echo "  install"
	@echo "  uninstall"
	@echo "  test"
	@echo "  test_ci"
	@echo "  test_irl"
	@echo "  clean"
	@echo "  distclean"
	@echo "  cmd-list"
	@echo ""
	@echo "Influential make variables:"
	@echo "  V                 - Build verbosity {0,1,2}."
	@echo "  BUILD_ENV_FLAGS   - Environment added to 'go build'."
	@echo ""
	@echo "Set env to build manually:"
	@echo " export GOPATH=$(GOPATH)"
	@echo " export GOPRIVATE=git.ovh.iot"
