#!/bin/sh
# Copyright (C) 2022 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

set -e
usage()
{
	echo "$0 <path/to/image>"
}

if [ $# -ne 1 ] ; then
	usage
	exit 64 # EX_USAGE
fi

set -x

target_image="$1"
os_definition="system.scm"
system="i686-linux"

rm -f "${target_image}"

minimum_size="$(du -bsL $(guix system build -s ${system} ${os_definition}) || true)"
minimum_size="$(echo ${minimum_size} | awk '{print $1}')"
minimum_size="$(expr ${minimum_size} + 1048576)" # Add 1MiB for the alignement and the MBR
# For some reasons we need more space otherwise we have the following error:
# guix system: error: fport_write: No space left on device
# Add 2595225600 computed by doing (3797 - 1322) * (1024*1024)
# guix system: warning: at least 3,796.2 MB needed but only 1,322.5 MB available in [...]
minimum_size="$(expr ${minimum_size} + 2595225600)"

qemu-img create -f raw "${target_image}" "${minimum_size}"
echo -e '+,\n' | sfdisk "${target_image}" # Create 1 Linux partition that takes all the space
# TODO: swap
loop="$(udisksctl loop-setup -f ${target_image} | awk '{print $5}' | sed 's#\.$##')"

# TODO: find a way to not need root
sudo cryptsetup luksFormat --type luks1 "${loop}p1"
unlocked_partition_name=cryptroot
unlocked_partition="/dev/mapper/${unlocked_partition_name}"
sudo cryptsetup open "${loop}p1" "${unlocked_partition_name}"
sudo mkfs.ext4 "${unlocked_partition}"
sleep 1 # Race condition: without the sleep, udisks doesn't mount the partition
mount_point="$(sudo -E udisksctl mount -b "${unlocked_partition}" | awk '{print $4}' | sed 's#\.$##g')"

partition_uuid="$(sudo blkid --probe -o value --match-tag UUID ${loop}p1)"
cp -f "${os_definition}" "${os_definition}.real"
sed "s#12345678-abcd-1234-1234-1234567899ab#${partition_uuid}#g" -i "${os_definition}.real"
sed "s#/dev/sda#${loop}#g"  -i "${os_definition}.real"

sudo -E guix system init -s "${system}" "${os_definition}.real" "${mount_point}"

sudo udisksctl unmount -b "${unlocked_partition}"
sudo cryptsetup close "${unlocked_partition_name}"
sudo udisksctl loop-delete -b "${loop}"

echo qemu-system-i386 -M pc -drive format=raw,file=${target_image} -m 2047M
