# Base directories
IMAGES_PATH := images
LIBRARY_PATH := library
SYMLINK_PREFIX := library_

# Docker registry variables
REGISTRY := git.unkin.net
OWNER := unkin
DATE_TAG := $(shell date +%Y%m%d)
SUFFIX=$(shell basename $$(mktemp -u) | cut -d . -f 2)
GIT_BRANCH=$(shell git symbolic-ref --short HEAD 2>/dev/null || echo $$GITHUB_HEAD_REF)
GIT_COMMIT := $(shell git rev-parse --short HEAD)

# Find all subdirectories under the IMAGES_PATH
DIRS := $(shell find $(IMAGES_PATH) -mindepth 3 -maxdepth 3 -type d | sed 's|$(IMAGES_PATH)/||')

.PHONY: list $(DIRS)

.DEFAULT_GOAL := default
default: clean
	./ci/build.sh

# Separate base images from others
BASE_IMAGES = $(filter %/base,$(DIRS))
OTHER_IMAGES = $(filter-out %/base,$(DIRS))

# Make all images, ensuring base images build first
all:
	@for dir in $(BASE_IMAGES); do \
		$(MAKE) $$dir; \
	done
	@for dir in $(OTHER_IMAGES); do \
		$(MAKE) $$dir; \
	done


# List all directories
list:
	@echo "Images:"
	@for dir in $(BASE_IMAGES); do \
		echo "  '$$dir'"; \
	done
	@for dir in $(OTHER_IMAGES); do \
		echo "  '$$dir'"; \
	done

# Dynamically create targets for each directory
.ONESHELL:
$(DIRS):
	@echo "Building for $@"

	# Export environment
	export VAULT_ADDR=https://vault.service.consul:8200
	export VAULT_TOKEN=$$(vault write -field=token auth/approle/login role_id=$$VAULT_ROLEID) && \
	eval $$(vault kv get -format=json kv/service/packer/builder/env | jq -r '.data.data | to_entries[] | "export \(.key)=\(.value)"')

	@echo "Environment retrieved for $@"

	# Check if on master branch
	@if [ "$(GIT_BRANCH)" = "master" ]; then \
		echo "Current branch is $(GIT_BRANCH), checking latest timestamp in consul."; \
		LAST_BUILD_TIMESTAMP=$$(consul kv get infra/packer/$@/timestamp || echo "0"); \
		CURRENT_TIME=$$(date +%s); \
		if [ $$((CURRENT_TIME - LAST_BUILD_TIMESTAMP)) -lt 86400 ]; then \
			LAST_COMMIT=$$(consul kv get infra/packer/$@/commit || echo "0"); \
			if [ "$$((LAST_COMMIT))" == "$(GIT_COMMIT)" ]; then \
				echo "Skipping build for $@. Same commit as last, and less than 24 hours since last build."; \
				exit 0; \
			fi; \
		fi; \
	fi

	# Link .hcl files
	@find $(LIBRARY_PATH) -name '*.hcl' -exec sh -c 'ln -sf $$PWD/{} $(IMAGES_PATH)/$@/$(SYMLINK_PREFIX)$$(basename {})' \;

	# Link builds
	@for build in $$(cat $(IMAGES_PATH)/$@/builds); do \
		ln -sf ../../../../builds/$${build}.pkr.hcl $(IMAGES_PATH)/$@/library_$${build}.build.pkr.hcl; \
	done

	# Build the image
	@(cd $(IMAGES_PATH)/$@ && \
	export DATE=$(DATE_TAG) && \
	export VERSION=$$(cat version) && \
	export OS_NAME=$$(echo $@ | cut -d'/' -f1) && \
	export OS_VERSION_FULL=$$(echo $@ | cut -d'/' -f2) && \
	export OS_IMAGE=$$(echo $@ | cut -d'/' -f3) && \
	export OS_VERSION_MAJOR=$$(echo $$OS_VERSION_FULL | cut -d'.' -f1) && \
	export DOCKER_SOURCE=$$OS_NAME:$$OS_VERSION_FULL && \
	export DOCKER_SERVER='git.unkin.net' && \
	export INCUS_SOURCE="images:$$OS_NAME/$$OS_VERSION_MAJOR" && \
	export SUFFIX=$(SUFFIX) && \
	export GIT_COMMIT=$(GIT_COMMIT) && \
	export GIT_BRANCH=$(GIT_BRANCH) && \
	export VAULT_ADDR=https://vault.service.consul:8200
	export VAULT_TOKEN=$$(vault write -field=token auth/approle/login role_id=$$VAULT_ROLEID) && \
	/usr/bin/packer init . && \
	/usr/bin/packer build . )

	# Update build timestamp and date in Consul if on master branch
	@if [ "$(GIT_BRANCH)" = "master" ]; then \
		echo "Current branch is $(GIT_BRANCH), updating consul."; \
		CURRENT_TIMESTAMP=$$(date +%s); \
		READABLE_DATE=$$(date '+%Y-%m-%d %H:%M:%S %Z'); \
		consul kv put infra/packer/$@/timestamp $$CURRENT_TIMESTAMP; \
		consul kv put infra/packer/$@/date "$$READABLE_DATE"; \
		consul kv put infra/packer/$@/commit "$(GIT_COMMIT)"; \
	fi

# Clean all symlinks
clean:
	@echo "Cleaning up symlinks..."
	@find $(IMAGES_PATH) -name 'library_*' -type l -delete
	@echo "All symlinks removed!"
