# Alpine VM Image Builder
# ------------------------
# Builds a bootable Alpine Linux disk image for Cloud Hypervisor direct boot.
#
# Usage:
#   make build          — generate GPG key + build qcow2 image
#   make build-raw      — build raw image (for Cloud Hypervisor direct boot)
#   make extract-kernel — extract kernel + initramfs from image
#   make clean          — remove build artifacts
#
# Configurable variables (override on command line):
#   IMAGE_SIZE      Size of the disk image (default: 4G)
#   ALPINE_BRANCH   Alpine release branch (default: latest-stable)
#   KERNEL_FLAVOR   Kernel variant (default: virt)
#   ALPINE_MIRROR   APK mirror (default: http://dl-cdn.alpinelinux.org/alpine)

SHELL := /bin/sh

# --- configurable ----------------------------------------------------
IMAGE_NAME    ?= alpine-vm
IMAGE_SIZE    ?= 4G
IMAGE_FORMAT  ?= qcow2
ALPINE_BRANCH ?= latest-stable
KERNEL_FLAVOR ?= virt
ALPINE_MIRROR ?= http://dl-cdn.alpinelinux.org/alpine
INITFS_FEATURES ?= kms scsi virtio

IMAGE_FILE     = $(IMAGE_NAME).$(IMAGE_FORMAT)
SCRIPT_DIR     = $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
OVERLAY_DIR    = $(SCRIPT_DIR)/overlay
CONFIGURE_SH   = $(SCRIPT_DIR)/configure.sh
GEN_GPG_SH     = $(SCRIPT_DIR)/gen-gpg-key.sh

# alpine-make-vm-image — download if not found
MAKE_VM_IMAGE  = $(SCRIPT_DIR)/alpine-make-vm-image
MAKE_VM_IMAGE_URL = https://raw.githubusercontent.com/alpinelinux/alpine-make-vm-image/v0.13.4/alpine-make-vm-image

# --- helper ----------------------------------------------------------

$(MAKE_VM_IMAGE):
	@echo ">>> Downloading alpine-make-vm-image ..."
	wget -q -O $@ $(MAKE_VM_IMAGE_URL)
	chmod +x $@

# --- GPG key ---------------------------------------------------------

.gpg-done: $(GEN_GPG_SH)
	@echo ">>> Generating GPG key ..."
	cd $(SCRIPT_DIR) && $(GEN_GPG_SH)
	@touch $@

# --- build -----------------------------------------------------------

build: .gpg-done $(MAKE_VM_IMAGE)
	@echo ">>> Building $(IMAGE_FILE) ..."
	@test -f $(OVERLAY_DIR)/root/gpg-key.asc || { \
		echo "ERROR: GPG key not found. Run 'make gpg-key' first." >&2; \
		exit 1; \
	}
	$(MAKE_VM_IMAGE) \
		--branch         $(ALPINE_BRANCH) \
		--image-format   $(IMAGE_FORMAT) \
		--image-size     $(IMAGE_SIZE) \
		--kernel-flavor  $(KERNEL_FLAVOR) \
		--mirror-uri     $(ALPINE_MIRROR) \
		--initfs-features '$(INITFS_FEATURES)' \
		--serial-console \
		--fs-skel-dir    $(OVERLAY_DIR) \
		--fs-skel-chown  root:root \
		--script-chroot \
		--packages       "python3 py3-yaml py3-pydantic git curl gnupg docker docker-cli-buildx docker-cli-compose" \
		$(IMAGE_FILE) \
		$(CONFIGURE_SH)
	@echo ">>> Image built: $(IMAGE_FILE)"
	@ls -lh $(IMAGE_FILE)

# Raw image (best for Cloud Hypervisor)
build-raw:
	$(MAKE) build IMAGE_FORMAT=raw

# Build without GPG key (for testing / CI without GPG)
build-no-gpg: $(MAKE_VM_IMAGE)
	@echo ">>> Building $(IMAGE_FILE) without GPG key ..."
	$(MAKE_VM_IMAGE) \
		--branch         $(ALPINE_BRANCH) \
		--image-format   $(IMAGE_FORMAT) \
		--image-size     $(IMAGE_SIZE) \
		--kernel-flavor  $(KERNEL_FLAVOR) \
		--mirror-uri     $(ALPINE_MIRROR) \
		--initfs-features '$(INITFS_FEATURES)' \
		--serial-console \
		--fs-skel-dir    $(OVERLAY_DIR) \
		--fs-skel-chown  root:root \
		--script-chroot \
		--packages       "python3 py3-yaml py3-pydantic git curl gnupg docker docker-cli-buildx docker-cli-compose" \
		$(IMAGE_FILE) \
		$(CONFIGURE_SH)
	@echo ">>> Image built: $(IMAGE_FILE)"
	@ls -lh $(IMAGE_FILE)

# --- kernel extraction -----------------------------------------------

extract-kernel: $(IMAGE_FILE)
	@echo ">>> Extracting kernel and initramfs from $(IMAGE_FILE) ..."
	@which guestmount >/dev/null 2>&1 || { \
		echo "ERROR: guestmount (libguestfs) required. Install: apk add libguestfs" >&2; \
		exit 1; \
	}
	@mkdir -p $(IMAGE_NAME)-boot
	guestmount -a $(IMAGE_FILE) -m /dev/sda --ro $(IMAGE_NAME)-boot
	cp $(IMAGE_NAME)-boot/boot/vmlinuz-$(KERNEL_FLAVOR) $(IMAGE_NAME)-vmlinuz
	cp $(IMAGE_NAME)-boot/boot/initramfs-$(KERNEL_FLAVOR) $(IMAGE_NAME)-initramfs
	guestunmount $(IMAGE_NAME)-boot
	rmdir $(IMAGE_NAME)-boot
	@echo ">>> Kernel  : $(IMAGE_NAME)-vmlinuz"
	@echo ">>> Initrd  : $(IMAGE_NAME)-initramfs"

# --- utilities -------------------------------------------------------

gpg-key: .gpg-done
	@echo ">>> GPG key ready"

gpg-fingerprint:
	@gpg --batch --fingerprint "builder@localhost" || echo "GPG key not found in host keyring"

# --- cleanup ---------------------------------------------------------

clean:
	rm -f $(IMAGE_FILE)
	rm -f $(IMAGE_NAME).raw
	rm -f $(IMAGE_NAME)-vmlinuz $(IMAGE_NAME)-initramfs
	rm -f .gpg-done
	rm -f $(MAKE_VM_IMAGE)
	rm -rf $(IMAGE_NAME)-boot
	@echo ">>> Cleaned (GPG key in overlay/ preserved — use 'make clean-all' to remove)"

clean-all: clean
	rm -f $(OVERLAY_DIR)/root/gpg-key.asc
	rm -f $(OVERLAY_DIR)/root/gpg-pubkey.asc
	@echo ">>> All artifacts cleaned"

.PHONY: build build-raw build-no-gpg extract-kernel gpg-key gpg-fingerprint clean clean-all
