#!/bin/bash

# tips here https://github.com/systemd/systemd/issues/6381

set -u
set -e
#set -x


SCRIPT=$(realpath ${BASH_SOURCE})
IMAGES=$(realpath $(dirname ${SCRIPT})/../build/images/)

image_file() {
    local fname=$(readlink -f ${IMAGES}/${1})
    if [[ ! -f ${fname} ]]; then
        >&2 printf "File ${fname} does not exist\n"
        exit 1
    fi
    printf $fname
}

EFIBOOT=$(image_file systemd-bootx64.efi)
KERNEL=$(image_file bzImage)
ROOTFS=$(image_file citadel-image-intel-corei7-64.ext2)

UUID="683a17fc-4457-42cc-a946-cde67195a101"


KERNEL_CMDLINE="add_efi_memmap intel_iommu=off cryptomgr.notests rcupdate.rcu_expedited=1 rcu_nocbs=0-64 tsc=reliable no_timer_check noreplace-smp i915.fastboot=1 quiet splash"

MOUNT_PATH=/tmp/citadel-boot-mount

TARGET=/dev/sdb
TARGET_BOOT=${TARGET}1
TARGET_LVM=${TARGET}2
PARTED="parted -a optimal ${TARGET}"

is_mounted() {
    echo "is mounted $1"
    for mnt in $(awk '{print $1}' < /proc/self/mounts); do
        [[ $mnt == $1 ]] && return 0
    done
    return 1
}

unmount_partition() {
    echo "unmount partition $1"
    if ! is_mounted $1 ; then
        printf "$1 is not mounted\n"
        return
    fi
}


unmount_device() {
    echo "unmount device"
    for p in ${TARGET}*; do
        is_mounted $p && unmount_partition $p
    done
    echo "done unmount device"
}

remove_volume() {
    local vg
    # find volume group name
    vg=$(pvs --noheadings -o vg_name ${1})
    # echo to strip whitespace
    [[ -n $(echo -n ${vg}) ]] && vgremove ${vg}
    pvremove ${1}
}

remove_volumes() {
    echo "remove volumes"
    for p in ${TARGET}*; do
        pvs ${p} && remove_volume ${p}
    done
    return 0
}

partition_device() {
    ${PARTED} -s mklabel gpt
    ${PARTED} mkpart boot fat32 0% 512MiB
    ${PARTED} set 1 boot on
    ${PARTED} mkpart data ext4 512MiB 100%
    ${PARTED} set 2 lvm on
    mkfs.vfat -F 32 ${TARGET_BOOT}
}

setup_luks() {
    printf "subgraph" | cryptsetup -q --uuid=${UUID} luksFormat ${TARGET_LVM} -
    printf "subgraph" | cryptsetup open --type luks --key-file - ${TARGET_LVM} e1
}

setup_lvm() {
    pvcreate -ff --yes /dev/mapper/e1
    vgcreate --yes citadel /dev/mapper/e1
    #pvcreate -ff ${TARGET_LVM}
    #vgcreate --yes citadel ${TARGET_LVM}
    lvcreate --yes --size 2g --name rootfsA citadel
    lvcreate --yes --size 2g --name rootfsB citadel
    lvcreate --yes --extents 100%VG --name storage citadel
    mkfs.ext4 /dev/mapper/citadel-storage
}

make_loader_conf() {
    echo "default bootA"
    echo "timeout 5"
}

make_boot_conf() {
    echo "title Subgraph OS (Airwolf Edition) [Root Partition ${1}]"
    echo "linux /bzImage"
    echo "options LABEL=Boot root=/dev/mapper/citadel-rootfs${1} ${KERNEL_CMDLINE}"
}

setup_efi() {
    mkdir -p ${MOUNT_PATH}
    mount ${TARGET_BOOT} ${MOUNT_PATH}
    mkdir -p ${MOUNT_PATH}/EFI/BOOT
    mkdir -p ${MOUNT_PATH}/loader/entries
    cp ${EFIBOOT} ${MOUNT_PATH}/EFI/BOOT/bootx64.efi
    cp ${KERNEL} ${MOUNT_PATH}/bzImage
    make_loader_conf > ${MOUNT_PATH}/loader/loader.conf
    make_boot_conf 'A' > ${MOUNT_PATH}/loader/entries/bootA.conf
    make_boot_conf 'B' > ${MOUNT_PATH}/loader/entries/bootB.conf
    umount ${MOUNT_PATH}
    rmdir ${MOUNT_PATH}
}

write_root() {
    echo "writing rootfsA"
    dd if=${ROOTFS} of=/dev/mapper/citadel-rootfsA bs=4M status=progress
    sync
}


blkdeactivate -v ${TARGET}
unmount_device
remove_volumes
partition_device
setup_luks
setup_lvm
setup_efi
write_root

vgchange -a n citadel
cryptsetup close e1