.PHONY: stop docker check-env
default: help;

###########
# VERSION #
###########
CMEM_ORCHESTRATION_VERSION?=$(shell git describe --always --dirty)

#########################
# ENVIRONMENT VARIABLES #
#########################
CONFIGFILE_BASE_DIRECTORY?=environments
CONFIGFILE?=${CONFIGFILE_BASE_DIRECTORY}/config.env
CMEMC_CONNECTION?=cmem

# GIT
MAKEOVERRIDES=
GITBRANCH=$(shell git rev-parse --abbrev-ref HEAD)

# DOCKER

CMD=$(shell which docker) compose ${DOCKER_CMD_ADD}
ifeq ($(CMD),)
	CMD=/usr/local/bin/docker
endif

include ${CONFIGFILE_BASE_DIRECTORY}/default.env
include ${CONFIGFILE}

# DEPLOYMENT SETTINGS
#DEPLOY_BASE_URL=${EXTERNAL_BASE_URL}
DEPLOY_BASE_URL=$(shell echo "${EXTERNAL_BASE_URL}" | sed -e 's|:80$$||' -e 's|:443$$||')

# PROJECT SETTINGS
PROJECT_NAME=${DEPLOYHOST}
COMPOSE_PROJECT_NAME=$(shell echo "${PROJECT_NAME}" | sed -e 's/[^a-zA-Z0-9]*//g')${PROJECT_NAME_SUFFIX}

include ${CONFIGFILE_BASE_DIRECTORY}/${MEMORY_SETTINGS}
export
# We cannot just overwrite ENV variables from the outside because that are already defined in CONFIGFILE. So we need to use alternative ENV vars.
ifneq ($(ALTERNATIVE_APACHE_BASE_FILE),)
	APACHE_BASE_FILE=$(ALTERNATIVE_APACHE_BASE_FILE)
endif

################
# CORE TARGETS #
################

# provides the up-to-date CMEMC run var
setup-cmemc-env:
ifneq (${CMEMC_CONNECTION}, cmem)
	$(if $(wildcard conf/cmemc/config.ini),,$(error "There is no /conf/cmemc/config.ini file, please link it to your local cmemc config to use your custom connection"))
	$(eval CMEMC := docker compose run -i --rm --volume $(shell pwd)/data:/data --volume $(shell pwd)/conf/cmemc/config.ini:/config/cmemc.ini cmemc -c ${CMEMC_CONNECTION})
else
	$(eval CMEMC := docker compose run -i --rm --env "OAUTH_CLIENT_SECRET=${CMEM_SERVICE_ACCOUNT_CLIENT_SECRET}" --volume $(shell pwd)/data:/data --volume $(shell pwd)/conf/cmemc/cmemc.ini:/config/cmemc.ini cmemc -c ${CMEMC_CONNECTION})
endif


# wait for healthy orchestration
wait-for-healthy:
	${DEST}/scripts/waitForSuccessfulStart.dist.sh

## default orchestration start from scratch (will remove all the data)
clean-pull-start-bootstrap:
	@make clean pull start bootstrap
	@echo ""
	@echo "CMEM-Orchestration successfully started with store ${EXPLORE_STORE}."
	@echo "Please open ${DEPLOY_BASE_URL} for validation."
	@echo "Run make logs to see log output"

## start the docker orchestration
start: init-log-dir up wait-for-healthy

## stop the docker orchestration
stop: check-env
	${CMD} stop

### force stop (kill) the docker orchestration
kill: check-env
	${CMD} kill

# init log directory structure
init-log-dir:
	@mkdir -p ${DEST}/logs/apache2
	@mkdir -p ${DEST}/logs/dataintegration
	@mkdir -p ${DEST}/logs/explore

# remove log dir
rm-log-dir:
	@rm -rf ${DEST}/logs

## Remove existing bootstrap data from triple store and import shipped data from Explore
bootstrap: setup-cmemc-env
	@echo "Remove existing bootstrap data from triple store and import shipped data from Explore"
	chmod a+r conf/cmemc/cmemc.ini
	${CMEMC} admin store bootstrap --import

## Run all system migrations, incl. bootstrap data if needed
migration: setup-cmemc-env
	@echo "Run all system migrations, incl. bootstrap data if needed"
	chmod a+r conf/cmemc/cmemc.ini
	${CMEMC} admin migration execute --filter tag system

### start without deleting existing data
up: update-backchannel-logout-url check-env
	${CMD} up -d

## follow the log output of all containers
logs: check-env
	${CMD} logs --tail=10 --follow

### Output complete orchestration logs (without following)
logs-all-no-follow: check-env
	${CMD} logs

## shutdown the docker orchestration and remove all volumes, orphaned containers and networks
down:
	${CMD} down --volumes --remove-orphans || exit 0
	$(shell which docker) volume prune -a -f --filter "label=com.docker.compose.project=${COMPOSE_PROJECT_NAME}"

### shutdown, clean logs, database files and data dumps
clean:
	@scripts/askForConsent.dist.sh "The target cleans up everything and esp. REMOVES ALL YOUR DATA. Do you want to continue?"
	make check-env kill stop down rm-log-dir
	# Note: -v is not the same as --volume!!
	${CMD} rm -v --force || exit 0

### shutdown, clean logs, database files, data dumps AND clean up repository (delete everything in .gitignore)
dist-clean:
	# NOTE: This target also purges the repository (deletes everything in .gitignore, e.g. ./data/backups)!
	@make clean
	# remove files which are ignored by git
	git clean -d --force -X
	rm -f ${DEST}/data/dataintegration/*

## pull the images from the docker registry
pull: check-env
	@# artifactory is sometimes down, we try it 5 times before we error
	@for i in 1 2 3 4 5; do ${CMD} pull && break || sleep 15; done

### remove a single service using docker-compose
remove-%:
	@echo "Removing $*"
	${CMD} rm -s -f $*

### restart a single service using docker-compose
restart-%:
	@echo "Restarting $*"
	${CMD} restart $*

### stop a single service using docker-compose
stop-%:
	@echo "Stopping $*"
	${CMD} stop $*

# check the environment if matching the requirements and required ENV are set
check-env: init-log-dir generate-env
	@if test -z "$(CMEM_SERVICE_ACCOUNT_CLIENT_SECRET)"; then echo "No CMEM_SERVICE_ACCOUNT_CLIENT_SECRET defined. Make sure to add one in your config.env file."; exit 1; fi
	@mkdir -p ${DEST}/data/backups
	@mkdir -p ${DEST}/data/python-packages
	@mkdir -p ${DEST}/data/dataintegration_reports
	@mkdir -p ${DEST}/data/dataintegration
	@mkdir -p ${DEST}/data/explore-companion
	@mkdir -p ${DEST}/data/explore-graphinsights
	@mkdir -p ${DEST}/data/graphinsights-extension
	@chmod o+w ${DEST}/data/*

### generate a .env file so you can run the CO with docker compose
generate-env:
	@env > .env.make
	@$(shell "env" > .env.system)
	@sort .env.make > .env.make.sorted
	@sort .env.system > .env.system.sorted
	@comm -3 .env.make.sorted .env.system.sorted > .env
	@rm .env.system .env.system.sorted .env.make .env.make.sorted

### update Keycloak back-channel logout URL in the database dump
update-backchannel-logout-url:
	@echo "--> Updating Keycloak back-channel logout URL to use ${DEPLOY_BASE_URL}"
	@sed -i "s|http://docker.localhost/graphinsights/logout/connect/back-channel/keycloak|${DEPLOY_BASE_URL}/graphinsights/logout/connect/back-channel/keycloak|g" conf/postgres/docker-entrypoint-initdb.d/keycloak_db.sql

### prints currently active component versions
version-list:
	@${DEST}/scripts/printComponentVersions.dist.sh

##############
# EXTENSIONS #
##############

# extensions are additional target included in additional *.Makefiles files
# under the the extensions folder. The extension mechanism can be disabled
# with the NO_EXTENSION=true variable

NO_EXTENSIONS?=false
ifneq ($(NO_EXTENSIONS), true)
	MAKEFILE_EXTENSIONS?=$(shell ls extensions/*.Makefile)
	-include ${MAKEFILE_EXTENSIONS}
endif

###############
# HELP SCREEN #
###############

## show this help screen
help:
	@printf "Available targets for project ${COMPOSE_PROJECT_NAME}:\n\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 "%-34s %s\n", helpCommand, helpMessage; \
		} \
	} \
	{ lastLine = $$0 }' $(MAKEFILE_LIST)

## show the extended help screen
help-extend: help help3

### show the extended help screen
help3:
	@printf "Available targets for project ${COMPOSE_PROJECT_NAME}:\n\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 "%-34s %s\n", helpCommand, helpMessage; \
		} \
	} \
	{ lastLine = $$0 }' $(MAKEFILE_LIST)
