#!/usr/bin/env bash

# Useful links:
# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/bootflow_2711.md
# https://www.raspberrypi.org/documentation/configuration/boot_folder.md
# https://www.raspberrypi.org/documentation/configuration/config-txt/boot.md
# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/

VM_NAME=gen_debian_raspi_64bit_default

WORK_DIR=/root
IMG_FILE=debian-rpi4.img
IMG_SIZE=1500M
IMG_DIR=/mnt
INIT_CMD="initialize.sh"
CHROOT_CMD="chroot_cmds.sh"
FINISH_CMD="terminate.sh"

# Debian seems to hardcode DNS servers that we will have to change:
sed -i -e '/nameserver/s/^\(.*\)$/#\1/g' \
    -e '/iface eth0/a dns-nameserver 192.168.121.1' /etc/network/interfaces
ifdown eth0
ifup eth0

cd "$WORK_DIR"

cat > "$INIT_CMD" <<EOF
apt update
#apt upgrade -y
apt install -y debootstrap qemu-user-static parted dosfstools

if [[ ! -e "$IMG_FILE" ]]; then
    fallocate -l "$IMG_SIZE" "$IMG_FILE"

    LOOP_DEV=\$(losetup -f -P --show "$IMG_FILE")
    parted "\$LOOP_DEV" "mklabel msdos"
    parted "\$LOOP_DEV" "mkpart p fat32   1 512"
    parted "\$LOOP_DEV" "mkpart p ext4  512  -1"

    mkfs.vfat "\${LOOP_DEV}p1"
    fatlabel "\${LOOP_DEV}p1" BOOT
    mkfs.ext4 -F "\${LOOP_DEV}p2"
    e2label "\${LOOP_DEV}p2" ROOT

    mount "\${LOOP_DEV}p2" "$IMG_DIR"
    mkdir -p "$IMG_DIR"/boot/firmware
    mount "\${LOOP_DEV}p1" "$IMG_DIR"/boot/firmware
fi

[[ -d "$IMG_DIR/etc" ]] || qemu-debootstrap --arch=arm64 testing "$IMG_DIR"

mount | grep "$IMG_DIR"/sys     || mount -o bind /sys     "$IMG_DIR"/sys
mount | grep "$IMG_DIR"/proc    || mount -o bind /proc    "$IMG_DIR"/proc
mount | grep "$IMG_DIR"/dev     || mount -o bind /dev     "$IMG_DIR"/dev
mount | grep "$IMG_DIR"/dev/pts || mount -o bind /dev/pts "$IMG_DIR"/dev/pts
EOF
chmod 0755 "$INIT_CMD"

cat > "$CHROOT_CMD" <<EOF
#!/usr/bin/env bash

sed -i 's/^\(deb.*testing main\)\$/\1 contrib non-free/1' /etc/apt/sources.list

apt update
apt upgrade -y
apt dist-upgrade -y
apt install -y ca-certificates linux-image-arm64 raspi-firmware rpi.gpio-common

echo 'SUBSYSTEM=="vchiq",GROUP="video",MODE="0660"' > /etc/udev/rules.d/10-vchiq-permissions.rules

echo raspi4 > /etc/hostname

sed -i 's/^\(.*\)console=ttyS[^ ]* \(.*\)\$/\1 \2/g' /boot/firmware/cmdline.txt
echo vfat >> /etc/initramfs-tools/modules

cat > /etc/fstab <<EOF2
/dev/mmcblk0p2 /              ext4  noatime,nodiratime,errors=remount-ro 0 1
/dev/mmcblk0p1 /boot/firmware vfat  noatime,nodiratime                   0 2
tmpfs          /tmp           tmpfs nosuid,nodev                         0 0
EOF2

cat > /etc/network/interfaces.d/lo <<EOF2
auto lo
iface lo inet loopback
EOF2

cat > /etc/network/interfaces.d/eth0 <<EOF2
auto eth0
iface eth0 inet dhcp
EOF2

update-initramfs -c -k all

EOF
# END OF "$CHROOT_CMD"
chmod 0755 "$CHROOT_CMD"

cat > "$FINISH_CMD" <<EOF
#!/usr/bin/env bash

umount /mnt/dev/pts
umount /mnt/dev
umount /mnt/proc
umount /mnt/sys

umount /mnt/boot/firmware
umount /mnt

LOOP_DEV=\$(losetup --associated $IMG_FILE --output NAME --noheadings)
losetup -d "\$LOOP_DEV"

echo "*********************************************************"
echo "Now, from the host, make a microSD available to the VM"
echo "with a command like this, for example":
echo
echo "    virsh attach-disk $VM_NAME /dev/mmcblk0 vdx --live"
echo
echo
echo "Now, in the VM, copy the Raspberry Pi image onto the microSD (be"
echo "VERY CAREFULL to specify the right device!!!):"
echo
echo "    dd if=$IMG_FILE of=/dev/vdb bs=4M oflag=dsync status=progress"
echo
echo
echo "This command will probably finish rather quickly because"
echo "the VM will do buffering. So, once the command terminates,"
echo "the following command, executed on the host, may take a"
echo "little longer:"
echo
echo "    virsh detach-disk $VM_NAME vdx --live"
echo
echo
echo "Now remove the microSD, put it into the Raspberry Pi and"
echo "boot it up."
echo
echo "*********************************************************"
EOF
chmod 0755 "$FINISH_CMD"

. "$INIT_CMD"
cp "$CHROOT_CMD" "$IMG_DIR/root/$CHROOT_CMD"
chroot "$IMG_DIR" /root/"$CHROOT_CMD"
