VERSION := development
GIT_REF := $(shell git log -1 --format=%H)
GIT_AUTHOR := $(shell git log -1 --format=%an)
GIT_PUBKEY := $(shell git log -1 --format=%GP)
GIT_TIMESTAMP := $(shell git log -1 --format=%cd --date=iso)
export

## Use env vars from latest release when reproducing
ifdef REPRODUCE
include dist/release.env
export
endif
ifdef NOCACHE
NO_CACHE := --no-cache
endif

.DEFAULT_GOAL :=
.PHONY: default
default: \
	out/release.env \
	out/manifest.txt \
	out/airgap.iso

## Primary targets

out/airgap.iso: Containerfile $(shell git ls-files rootfs)
	SOURCE_DATE_EPOCH=1 \
	docker build \
		--progress=plain \
		--output type=local,rewrite-timestamp=true,dest=out \
		--build-arg SOURCE_DATE_EPOCH=1 \
		--build-arg VERSION="$(VERSION)" \
		--build-arg GIT_REF="$(GIT_REF)" \
		--build-arg GIT_AUTHOR="$(GIT_AUTHOR)" \
		--build-arg GIT_PUBKEY="$(GIT_PUBKEY)" \
		--build-arg GIT_TIMESTAMP="$(GIT_TIMESTAMP)" \
		$(NO_CACHE) \
		-f Containerfile \
		.

## Development Targets

.PHONY: vm
vm: vm-bios

.PHONY: vm-bios
vm-bios: out/airgap.iso
	qemu-system-x86_64 \
		-m 4G \
		-machine pc \
		-serial stdio \
		-usb \
		-device sdhci-pci \
		-device sd-card,drive=external \
		-usbdevice tablet \
		-drive id=external,if=none,format=raw,file=out/sdcard.img \
		-display gtk,show-menubar=off,zoom-to-fit=on \
        -device usb-storage,drive=usbdrive \
        -drive id=usbdrive,if=none,format=raw,file=out/airgap.iso \
		-boot order=c

.PHONY: vm-efi
vm-efi: out/airgap.iso
	qemu-system-x86_64 \
		-m 4G \
		-machine pc \
		-serial stdio \
		-bios /usr/share/ovmf/OVMF.fd \
		-usb \
		-device sdhci-pci \
		-device sd-card,drive=external \
		-usbdevice tablet \
		-drive id=external,if=none,format=raw,file=out/sdcard.img \
		-display gtk,show-menubar=off,zoom-to-fit=on \
        -device usb-storage,drive=usbdrive \
        -drive id=usbdrive,if=none,format=raw,file=out/airgap.iso \
		-boot order=c

## Signing, Verification, and Release Targets

.PHONY: clean
clean:
	rm -rf out

.PHONY: release
release: clean
	rm -rf dist/*
	$(MAKE) NOCACHE=1 VERSION=$(VERSION)
	cp -R out/release.env out/airgap.iso out/manifest.txt dist/

.PHONY: sign
sign:
	set -e; \
	git config --get user.signingkey 2>&1 >/dev/null || { \
		echo "Error: git user.signingkey is not defined"; \
		exit 1; \
	}; \
	fingerprint=$$(\
		git config --get user.signingkey \
		| sed 's/.*\([A-Z0-9]\{16\}\).*/\1/g' \
	); \
	gpg --armor \
		--detach-sig  \
		--output dist/manifest.$${fingerprint}.asc \
		dist/manifest.txt

.PHONY: verify
verify: | dist/manifest.txt
	set -e; \
	for file in dist/manifest.*.asc; do \
		echo "\nVerifying: $${file}\n"; \
		gpg --verify $${file} dist/manifest.txt; \
	done;

.PHONY: reproduce
reproduce: clean | out
	$(MAKE) REPRODUCE=true NOCACHE=1
	diff -q out/manifest.txt dist/manifest.txt;

out:
	mkdir -p $@

out/release.env: $(shell git ls-files) | out
	echo 'VERSION=$(VERSION)'              > out/release.env
	echo 'GIT_REF=$(GIT_REF)'             >> out/release.env
	echo 'GIT_AUTHOR=$(GIT_AUTHOR)'       >> out/release.env
	echo 'GIT_PUBKEY=$(GIT_PUBKEY)'             >> out/release.env
	echo 'GIT_TIMESTAMP=$(GIT_TIMESTAMP)' >> out/release.env

out/manifest.txt: out/airgap.iso out/release.env | out
	openssl sha256 -r \
		out/airgap.iso \
		out/release.env \
	| sed -e 's/ \*out\// /g' -e 's/ \.\// /g' \
	> $@