export ECC_IMAGE_PREFIX=$(shell cat ./Dockerfile | egrep "^ENV ECC_IMAGE_PREFIX " | cut -d ' ' -f 3)
export ECC_IMAGE_NAME=$(shell cat ./Dockerfile | egrep "^ENV ECC_IMAGE_NAME " | cut -d ' ' -f 3)
export CONTAINER_NAME=${ECC_IMAGE_PREFIX}-${ECC_IMAGE_NAME}
export KILLTIMEOUT=10
# https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
export DOCKER_BUILDKIT=1
TIME_STAMP=$(shell date --iso-8601=seconds)

# git investigation
# Bamboo will set the current git branch in bamboo_repository_git_branch,
# gitlab will set the current git branch in CI_COMMIT_REF_NAME
# if the variable is not set (e.g. locally), we just use git to get it
ifdef bamboo_repository_git_branch
export GITBRANCH=${bamboo_repository_git_branch}
endif
ifdef CI_COMMIT_REF_NAME
export GITBRANCH=${CI_COMMIT_REF_NAME}
endif
ifndef GITBRANCH
export GITBRANCH=$(shell git rev-parse --abbrev-ref HEAD)
endif
# same for git describe
bamboo_inject_git_describe ?= $(shell git describe --always --dirty)
export GITDESCRIBE=${bamboo_inject_git_describe}

# our private registry
export REGISTRY_HOST=docker-registry.eccenca.com

export IMAGE_NAME=${CONTAINER_NAME}:${GITDESCRIBE}

# create the main tag (latest / develop / unknown)
export TAG_SUFFIX=$(subst /,_,$(GITBRANCH))
ifeq ($(GITBRANCH), master)
	export TAG_SUFFIX=latest
endif

# add an additional tag based on branch name (master -> latest)
export TAG_BRANCH=${REGISTRY_HOST}/${CONTAINER_NAME}:${TAG_SUFFIX}

# add primary tag based on git versioning
export TAG_VERSION=${REGISTRY_HOST}/${CONTAINER_NAME}:${GITDESCRIBE}
ifeq ($(GITBRANCH), master)
export TAG_MAJOR=$(shell bash ./includes/scripts/getTag.sh "major" "${REGISTRY_HOST}/${CONTAINER_NAME}" "${GITDESCRIBE}")
export TAG_MINOR=$(shell bash ./includes/scripts/getTag.sh "minor" "${REGISTRY_HOST}/${CONTAINER_NAME}" "${GITDESCRIBE}")
endif

export DOCKER_CMD=docker
ifneq ($(ECC_HOST),)
	export DOCKER_CERT_PATH=$(HOME)/.config/ssl/docker-eccenca
	export DOCKER_HOST=https://${ECC_HOST}.eccenca.com:2375
	export DOCKER_TLS_VERIFY=true
	export DOCKER_CMD=docker --tlsverify --tlscacert=${DOCKER_CERT_PATH}/ca.pem --tlscert=${DOCKER_CERT_PATH}/client-cert.pem --tlskey=${DOCKER_CERT_PATH}/client-key.pem -H=$(ECC_HOST).eccenca.com:2375
endif

.DEFAULT_GOAL := help

before-build:
	@echo "executed target before-build"

after-build:
	@echo "executed target after-build"

before-push:
	@echo "executed target before-push"

after-push:
	@echo "executed target after-push"

-include custom.Makefile

LS_BUILD_DATE=--label "org.label-schema.build-date=${TIME_STAMP}"
LS_VCS_REF=--label "org.label-schema.vcs-ref=${GITDESCRIBE}"
LS_VERSION=--label "org.label-schema.version=${TAG_VERSION}"
LS_SCHEMA_VERSION=--label "org.label-schema.schema-version=1.0.0-rc.1"
LABEL_SCHEMA=${LS_BUILD_DATE} ${LS_VCS_REF} ${LS_VERSION} ${LS_SCHEMA_VERSION}

## build the image based on Dockerfile
build:
	make before-build
	$(DOCKER_CMD) build -t ${IMAGE_NAME} ${LABEL_SCHEMA} .
	make after-build

## build the image based on Dockerfile (pull base images and ignore cache)
clean-build:
	make before-build
	$(DOCKER_CMD) build --pull=true --no-cache -t ${IMAGE_NAME} ${LABEL_SCHEMA} .
	make after-build

get-ports:
	@# go format templates, sed replacing and awk script: there should be a less expensive solution for this :-)
	$(eval PORTS=$(shell $(DOCKER_CMD) inspect -f '{{range $$port, $$map := .Config.ExposedPorts }} {{$$port}}{{end}}' ${IMAGE_NAME} | sed -e 's/^[[:space:]]*//' | awk 'BEGIN{RS=" "; FS="/"; ORS=" "}{print "-p " $$1 ":" $$1}'))

## start a container which deletes automatically
test: get-ports
	$(DOCKER_CMD) run -i -t --name=${CONTAINER_NAME} --rm ${PORTS} ${IMAGE_NAME}

## test tag name generation
name:
	@echo tag = $(TAG_VERSION)
	@echo host = $(ECC_HOST)
	@echo cmd = $(DOCKER_CMD)

## start a container in the background
run: get-ports
	$(DOCKER_CMD) run -d --name=${CONTAINER_NAME} ${PORTS} ${IMAGE_NAME}

## stop the default named container
stop:
	$(DOCKER_CMD) stop ${CONTAINER_NAME}

## start the default named container
start:
	$(DOCKER_CMD) start ${CONTAINER_NAME}

## follow the logs of the default named container
logs:
	$(DOCKER_CMD) logs -f ${CONTAINER_NAME}

## kill the default named container
kill:
	$(DOCKER_CMD) kill ${CONTAINER_NAME}

## rm the default named container
rm:
	$(DOCKER_CMD) rm -v -f ${CONTAINER_NAME}

## rm the default named image
rmi:
	$(DOCKER_CMD) image rm ${IMAGE_NAME} ${TAG_VERSION}

## inspect the image by starting a shell session in a self-destructing container
shell: get-ports
	$(DOCKER_CMD) run -i -t --rm ${PORTS} ${IMAGE_NAME} bash

## save a local image to a tar file
save:
	$(DOCKER_CMD) save -o ${CONTAINER_NAME}-${GITDESCRIBE}.tar ${IMAGE_NAME}

## tag the local image with a registry tag
tag:
	$(DOCKER_CMD) tag ${IMAGE_NAME} ${TAG_VERSION}
	$(DOCKER_CMD) tag ${IMAGE_NAME} ${TAG_BRANCH}
ifeq ($(GITBRANCH), master)
	$(DOCKER_CMD) tag ${IMAGE_NAME} ${TAG_MINOR}
	$(DOCKER_CMD) tag ${IMAGE_NAME} ${TAG_MAJOR}
endif

## push the local image to the registry
push: tag
	make before-push
	$(DOCKER_CMD) push ${TAG_VERSION}
	$(DOCKER_CMD) push ${TAG_BRANCH}
	make after-push
ifeq ($(GITBRANCH), master)
	$(DOCKER_CMD) push ${TAG_MINOR}
	$(DOCKER_CMD) push ${TAG_MAJOR}
endif

## pull the image from the registry and tag it in order to use other targets
pull:
	$(DOCKER_CMD) pull ${TAG_BRANCH}
	$(DOCKER_CMD) tag ${TAG_BRANCH} ${IMAGE_NAME}
	$(DOCKER_CMD) tag ${TAG_BRANCH} ${TAG_VERSION}

## clean build (used as bamboo-task)
bamboo-build: clean-build tag check-security

## tagging and pushing (used as bamboo-task)
bamboo-push: push rmi

## deploy the created image according to the deploy.conf
deploy:
	@cat deploy.conf 2>/dev/null >/dev/null
	$(eval ECC_DEPLOY_VHOST := $(shell cat ./deploy.conf | egrep "^vhost:" | cut -d ':' -f 2))
	$(eval ECC_DEPLOY_DOCKERPORT := $(shell cat ./deploy.conf | egrep "^dockerport:" | cut -d ':' -f 2))
	$(eval ECC_DEPLOY_ADDS := $(shell cat ./deploy.conf | egrep "^additionals:" | cut -d ':' -f 2-))
	${DOCKER_CMD} stop --time=${KILLTIMEOUT} ${ECC_DEPLOY_VHOST}_${ECC_IMAGE_NAME} || echo "Could not stop ${ECC_DEPLOY_VHOST}_${ECC_IMAGE_NAME}, container does not exist"
	${DOCKER_CMD} rm -v ${ECC_DEPLOY_VHOST}_${ECC_IMAGE_NAME} || echo "Could not remove volume ${ECC_DEPLOY_VHOST}_${ECC_IMAGE_NAME}, volume does not exist."
	${DOCKER_CMD} run -d --restart=always --name="${ECC_DEPLOY_VHOST}_${ECC_IMAGE_NAME}" ${ECC_DEPLOY_ADDS} -p ${ECC_DEPLOY_DOCKERPORT}:80 ${TAG_BRANCH}

## create the deploy script for bamboo
deploy-script:
	@cat deploy.conf 2>/dev/null >/dev/null
	$(eval ECC_DEPLOY_VHOST := $(shell cat ./deploy.conf | egrep "^vhost:" | cut -d ':' -f 2))
	$(eval ECC_DEPLOY_DOCKERPORT := $(shell cat ./deploy.conf | egrep "^dockerport:" | cut -d ':' -f 2))
	$(eval ECC_DEPLOY_ADDS := $(shell cat ./deploy.conf | egrep "^additionals:" | cut -d ':' -f 2-))
	rm -rf target
	mkdir target
	touch target/deploy.sh && chmod a+x target/deploy.sh
	echo "$(DOCKER_CMD) pull ${TAG_BRANCH} || exit 1" >>target/deploy.sh
	echo ${DOCKER_CMD} stop --time=${KILLTIMEOUT} ${ECC_DEPLOY_VHOST}_${ECC_IMAGE_NAME} >>target/deploy.sh
	echo ${DOCKER_CMD} rm -v ${ECC_DEPLOY_VHOST}_${ECC_IMAGE_NAME} >>target/deploy.sh
	echo ${DOCKER_CMD} run -d --restart=always --name=\"${ECC_DEPLOY_VHOST}_${ECC_IMAGE_NAME}\" ${ECC_DEPLOY_ADDS} -p ${ECC_DEPLOY_DOCKERPORT}:80 ${TAG_BRANCH} >>target/deploy.sh

TRIVY_SCAN?=true
TRIVY_IMAGE?=aquasec/trivy:latest
TRIVY_ADDITIONAL_OPTIONS?=--scanners vuln --severity HIGH,CRITICAL --timeout 15m
TRIVY=$(DOCKER_CMD) run --rm -v /var/run/docker.sock:/var/run/docker.sock -v ${HOME}/.cache/:/root/.cache/ -v $(shell pwd):/data ${TRIVY_IMAGE} image
## trivy security scan on the build image with xml and html output (xml ignores unfixed)
check-security:
ifeq ($(TRIVY_SCAN),true)
	rm -f trivy-security-scan-results.*
	date
	${TRIVY} ${TRIVY_ADDITIONAL_OPTIONS} --format template --template "@contrib/junit.tpl" --ignore-unfixed -o /data/trivy-security-scan-results.xml ${IMAGE_NAME}
	date
	${TRIVY} ${TRIVY_ADDITIONAL_OPTIONS} --format template --template "@contrib/html.tpl" -o /data/trivy-security-scan-results.html ${IMAGE_NAME}
	date
	${TRIVY} ${TRIVY_ADDITIONAL_OPTIONS} --format json -o /data/trivy-security-scan-results.json ${IMAGE_NAME}
	date
else
	@echo "***************************************"
	@echo "Trivy scan disabled (TRIVY_SCAN=false)."
	@echo "***************************************"
endif

## show this help screen
help:
	@printf "Available targets\n\n"
	@awk '/^[a-zA-Z\-\_0-9]+:/ { \
		helpMessage = match(lastLine, /^## (.*)/); \
		if (helpMessage) { \
			helpCommand = substr($$1, 0, index($$1, ":")-1); \
			helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \
			printf "%-15s %s\n", helpCommand, helpMessage; \
		} \
	} \
	{ lastLine = $$0 }' $(MAKEFILE_LIST)
