SHELL=bash

export CONTAINER_COMMAND ?= podman
export CONTAINER_INTERACTIVE
export CONTAINER_PORTS
export IN_CONTAINER ?= false
export IN_CI ?= false
export WATCH
export db ?= -cf
export DEV_PORT_HTTP
export DEV_PORT_HTTPS

###########################
##### GENERAL TARGETS #####

.PHONY: help
help:
	@echo "Nothing to see here, go away"

.PHONY: all
all:
	@echo "TODO"

.PHONY: clean
clean:
	rm -rf node_modules .npm .cache assets/icons assets/favicons static well-known 
	rm -rf .stack .stack-work .stack-work-build .stack-work-run .stack-work-test .stack-work-doc
	rm -rf bin/ .Dockerfile .dev-port-http .dev-port-https
.PHONY: clean-all
clean-all: clean
	$(CONTAINER_COMMAND) system prune --all --force --volumes
	$(CONTAINER_COMMAND) image prune --all --force
	$(CONTAINER_COMMAND) volume prune --force

.PHONY: release
release:
	./.gitlab-ci/version.pl -changelog CHANGELOG.md
	git add CHANGELOG.md
	VERSION=`.gitlab-ci/version.pl`
	git tag ${VERSION}
	git commit -m "chore(release): ${VERSION}"
	git push

.PHONY: %-shell
%-shell:
	MOUNT_DIR=/mnt/fradrive ; \
	FRADRIVE_SERVICE=$* ; \
	$(MAKE) -- --image-build FRADRIVE_SERVICE=$${FRADRIVE_SERVICE} ; \
	$(CONTAINER_COMMAND) run -it -v $(PWD):$${MOUNT_DIR} $(CONTAINER_PORTS) --env IN_CONTAINER=true --entrypoint /bin/bash --name fradrive.$${FRADRIVE_SERVICE}.interactive.$$(date +'%Y-%m-%dT%H-%M-%S') fradrive/$${FRADRIVE_SERVICE}

##### GENERAL TARGETS #####
###########################


############################################
##### UNIFIED FRONTEND/BACKEND TARGETS #####

.PHONY: serve
serve: CONTAINER_INTERACTIVE=-it
serve:
	$(MAKE) serve-database &
	$(MAKE) serve-frontend &
	$(MAKE) serve-backend

.PHONY: compile
compile: compile-frontend compile-backend

.PHONY: lint
lint: lint-frontend lint-backend

.PHONY: test
test: test-frontend test-backend i18n-check

##### UNIFIED FRONTEND/BACKEND TARGETS #####
############################################


############################
##### FRONTEND TARGETS #####

.PHONY: %-frontend
%-frontend: FRADRIVE_SERVICE=frontend
%-frontend: --image-build --containerized---%-frontend;

.PHONY: --%-frontend
--%-frontend: --containerized---frontend-dependencies-frontend;

.PHONY: --compile-frontend
--compile-frontend: --frontend-dependencies
	npx -- webpack --progress $(WATCH)

.PHONY: serve-frontend
serve-frontend: CONTAINER_INTERACTIVE=-it
serve-frontend:
	$(MAKE) -- --containerized---compile-frontend WATCH=--watch

# .PHONY: --serve-frontend
# --serve-frontend: WATCH=--watch
# --serve-frontend: --compile-frontend;

.PHONY: --lint-frontend
--lint-frontend: eslint.config.js
	npx -- eslint frontend/src $(FIX)
	@echo Hooray! There are no hints.

.PHONY: --test-frontend
--test-frontend: karma.conf.cjs
	@echo Karma frontend tests are currently broken after npm update and have therefor been temporarily disabled.
# npx -- karma start --conf karma.conf.cjs $(WATCH)

.PHONY: --frontend-dependencies
--frontend-dependencies: node_modules package.json package-lock.json assets;

node_modules: package.json package-lock.json
	npm ci --cache .npm --prefer-offline

package-lock.json: package.json
	npm install --cache .npm --prefer-offline

assets: assets/favicons assets/icons
assets/favicons:
	./utils/faviconize.pl assets/favicon.svg long assets/favicons
assets/icons: node_modules
	./utils/renamer.pl node_modules/@fortawesome/fontawesome-free/svgs/solid utils/rename-fa.json assets/icons/fradrive
	./utils/renamer.pl node_modules/@fortawesome/fontawesome-free/svgs/regular utils/rename-fa.json assets/icons/fradrive

well-known: node_modules assets
	npx webpack --progress

##### FRONTEND TARGETS #####
############################


###########################
##### BACKEND TARGETS #####

.PHONY: %-backend
%-backend: FRADRIVE_SERVICE=backend
%-backend: --image-build --containerized---%-dev-backend;

.PHONY: %-prod-backend
%-prod-backend: FRADRIVE_SERVICE=backend
%-prod-backend: --image-build --containerized---%-prod-backend;

.PHONY: --%-dev-backend
--%-dev-backend: FRADRIVE_SERVICE=backend
--%-dev-backend: stackopts=--flag uniworx:dev
--%-dev-backend: --image-build --containerized---%-backend;

.PHONY: --%-prod-backend
--%-prod-backend: FRADRIVE_SERVICE=backend
--%-prod-backend: stackopts=--flag uniworx:-dev
--%-prod-backend: --image-build --containerized-%-backend;

.PHONY: serve-backend
serve-backend: CONTAINER_INTERACTIVE=-it
serve-backend:
	DEV_PORT_HTTP=`docker/backend/dev_port.pl 3000 | tee .dev-port-http`; \
	DEV_PORT_HTTPS=`docker/backend/dev_port.pl 3443 | tee .dev-port-https`; \
	$(MAKE) -- --containerized---serve-dev-backend DEV_PORT_HTTP=$${DEV_PORT_HTTP} DEV_PORT_HTTPS=$${DEV_PORT_HTTPS}
.PHONY: --serve-dev-backend
--serve-dev-backend: start.sh
	DEV_PORT_HTTP=`cat .dev-port-http`; \
	DEV_PORT_HTTPS=`cat .dev-port-https`; \
	./start.sh

.PHONY: --compile-backend
--compile-backend:
	stack build --fast --profile --library-profiling --executable-profiling --flag uniworx:-library-only --local-bin-path $$(pwd)/bin $(stackopts)

.PHONY: --lint-backend
--lint-backend:
	stack build --test --fast --flag uniworx:library-only uniworx:test:hlint $(stackopts)

.PHONY: --test-backend
--test-backend:
	stack build --test --coverage --fast --flag uniworx:library-only $(stackopts)

# TODO: maybe deprecated
.PHONY: database
database: .stack compile-backend-prod
	export SERVER_SESSION_ACID_FALLBACK=$${SERVER_SESSION_ACID_FALLBACK:-true}
	export AVSPASS=$${AVSPASS:-nopasswordset}
	stack exec uniworxdb -- $(db)

.PHONY: serve-database
serve-database: CONTAINER_INTERACTIVE=-it
serve-database: --containerized-database

.PHONY: database-%
database-%:
	@echo "This target, intended to fill, clear, migrate, ... the database using uniworxdb from inside the backend container is yet to be implemented"
	exit 1

# .PHONY: .stack
.stack: stack.yaml stack.yaml.lock
.stack:
	$(MAKE) -- --image-run---.stack
.PHONY: --.stack
--.stack: stack.yaml stack.yaml.lock
	stack build --fast --only-dependencies $(stackopts)

# TODO: deprecated, remove
# .stack-work.lock:
# 	[ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en .stack-work.lock "$0" "$@" || :

##### BACKEND TARGETS #####
###########################


#############################
##### CONTAINER TARGETS #####

.PHONY: --containerized-database
--containerized-database: FRADRIVE_SERVICE=database
# port forwarding is disabled in --network=host mode; nevertheless it is stated here for documentation reasons
--containerized-database: CONTAINER_PORTS=-p 5432:5432/tcp
--containerized-database: --image-build
	if [ "$(IN_CONTAINER)" == "false" ] ; then \
	  $(CONTAINER_COMMAND) run -it $(CONTAINER_PORTS) --name fradrive.$(FRADRIVE_SERVICE).$$(date +'%Y-%m-%dT%H-%M-%S') fradrive/$(FRADRIVE_SERVICE) ; \
	fi

.PHONY: --containerized-%-frontend
--containerized-%-frontend: FRADRIVE_SERVICE=frontend
#--containerized-%-frontend: --image-build --image-run-%-frontend;
--containerized-%-frontend: --image-build
	$(MAKE) -- --image-run-$*-frontend

.PHONY: --containerized-%-backend
--containerized-%-backend: FRADRIVE_SERVICE=backend
#--containerized-%-backend: --image-build --image-run-%-backend;
--containerized-%-backend: CONTAINER_PORTS=-p 127.0.0.1:$(DEV_PORT_HTTP):3000/tcp -p 127.0.0.1:$(DEV_PORT_HTTPS):3443/tcp
--containerized-%-backend: --image-build
	$(MAKE) -- --image-run-$*-backend 

.PHONY: image-rebuild
image-rebuild-%:
	$(MAKE) -- --image-build FRADRIVE_SERVICE=$* NO_CACHE=--no-cache
.PHONY: --image-build
--image-build:
	rm -f .Dockerfile
	ln -s docker/$(FRADRIVE_SERVICE)/Dockerfile .Dockerfile
	MOUNT_DIR=/mnt/fradrive; \
	PROJECT_DIR=/mnt/fradrive; \
	if [ "$(IN_CI)" == "true" ] ; then \
	  PROJECT_DIR=/fradrive; \
	fi; \
	if [ "$(IN_CONTAINER)" == "false" ] ; then \
	  $(CONTAINER_COMMAND) build $(NO_CACHE) -v $(PWD):$${MOUNT_DIR} --env IN_CONTAINER=true --build-arg MOUNT_DIR=$${MOUNT_DIR} --build-arg PROJECT_DIR=$${PROJECT_DIR} --tag fradrive/$(FRADRIVE_SERVICE) --file $(PWD)/.Dockerfile ; \
	fi

.PHONY: --image-run-%
--image-run-%:
	MOUNT_DIR=/mnt/fradrive; \
	if [ "$(IN_CONTAINER)" == "true" ] ; then \
	  $(MAKE) -- $* ; \
	else \
	  $(CONTAINER_COMMAND) run $(CONTAINER_INTERACTIVE) -v $(PWD):$${MOUNT_DIR} $(CONTAINER_PORTS) --env IN_CONTAINER=true --env FRADRIVE_MAKE_TARGET=$* --env WATCH=$(WATCH) --name fradrive.$(FRADRIVE_SERVICE).$$(date +'%Y-%m-%dT%H-%M-%S') fradrive/$(FRADRIVE_SERVICE) ; \
	fi

##### CONTAINER TARGETS #####
#############################


.PHONY: i18n-check
i18n-check: --image-run---i18n-check
.PHONY: --i18n-check
--i18n-check:
	./missing-translations.sh
	@echo No missing translations.

%.lock:
	[ -e $@ ] || touch $@
	flock -en $@ true
