#!/usr/bin/env bash
# vim:et:ts=2:sts=2:sw=2
# shellcheck disable=SC2218

# Get absolute repository root (especially when symlinked)
ROOT="$(realpath "$(dirname "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")")"

# Load accompanying bash library
source "$ROOT/lib/lib.bash"

# Exit now if run as a regular user
assert-is-root

DISK="$1"
if [ -z "$DISK" ] || [ -n "$HELP" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
  say "
  USAGE:
    $(g "${BASH_SOURCE##*/}")  $(c /dev/sdx)

  DESCRIPTION:
    $(g "${BASH_SOURCE##*/}") installs and configures bootloaders for the
    TechLit system on $(c /dev/sdx).
"
  exit 1
fi

# Mountpoint to use
PREFIX="${PREFIX:-"$(mktemp -d)"}"

set-partitions "$DISK"

say "Mounting system (and un-mounting on errors or exit)"
{
  cleanup() {
    say "Un-mounting system"
    run umount -qR "$PREFIX"
    tl-chroot-unmount
  }

  run mount "$ROOT_PART" -o subvol="@root" "$PREFIX"
  run mount "$ROOT_PART" -o subvol="@srv" "$PREFIX/srv"
  run mount "$EFI_PART" "$PREFIX/boot/efi"
  tl-chroot-mount
}

say "Updating fstab"
{
  root_uuid="$(get_uuid "$ROOT_PART")"
  efi_uuid="$(get_uuid "$EFI_PART")"

  run root-write "$PREFIX/etc/fstab" "UUID=$root_uuid           /              btrfs rw,relatime,subvol=@root          0 1
UUID=$root_uuid           /srv           btrfs rw,relatime,subvol=@srv           0 2
UUID=$root_uuid           /var/btrfs     btrfs rw,relatime                       0 2
UUID=$efi_uuid            /boot/efi      vfat  rw,relatime                       0 2
/var/btrfs/@swap/swapfile none           swap  sw                                0 0
tmpfs                     /tmp           tmpfs rw,mode=1777,nosuid,nodev,noatime 0 0
"
}

say "Building initrd"
{
  run root-chroot "mkinitcpio -P"
}

SBAT="$ROOT"/roles/global/sbat.csv
GRUB_MODULES="all_video boot btrfs cat chain configfile echo efifwsetup efinet \
ext2 fat font gettext gfxmenu gfxterm gfxterm_background gzio halt help hfsplus \
iso9660 jpeg keystatus loadenv loopback linux ls lsefi lsefimmap lsefisystab \
lssal memdisk minicmd normal ntfs part_apple part_msdos part_gpt password_pbkdf2 \
png probe reboot regexp search search_fs_uuid search_fs_file search_label sleep \
smbios squash4 test true video xfs zfs zfscrypt zfsinfo cpuid play tpm cryptodisk \
gcry_arcfour gcry_blowfish gcry_camellia gcry_cast5 gcry_crc gcry_des gcry_dsa \
gcry_idea gcry_md4 gcry_md5 gcry_rfc2268 gcry_rijndael gcry_rmd160 gcry_rsa \
gcry_seed gcry_serpent gcry_sha1 gcry_sha256 gcry_sha512 gcry_tiger gcry_twofish \
gcry_whirlpool luks lvm mdraid09 mdraid1x raid5rec raid6rec \
keylayouts usbms usb_keyboard udf ext2 reiserfs"

if [ -d /sys/firmware/efi ] && command -p mokutil >/dev/null 2>&1; then
  if [ "$(sudo mokutil --sb-state | head -n1 | awk '{print $2}')" == 'enabled' ]; then
    secure_params+=("--sbat=$SBAT" "--disable-shim-lock" "--modules=$GRUB_MODULES")
  fi
fi

if [ ! -d /sys/firmware/efi ]; then
  grub_archs=(i386-pc)
elif is-t2-chip; then
  grub_archs=(x86_64-efi)
else
  grub_archs=(i386-efi x86_64-efi)
fi

role="$(jq -r '.role' /srv/secure/config.json)" || role="installer"
for arch in "${grub_archs[@]}"; do
  say "Installing $(c "$arch") bootloader"
  run sudo grub-install \
    --force --recheck --removable --skip-fs-probe \
    --target="$arch" \
    "${secure_params[@]}" \
    --efi-directory="$PREFIX/boot/efi" $NONVRAM \
    --boot-directory="$PREFIX/boot" \
    "$DISK"
  if [[ $role =~ ^(installer|recovery)$ ]] && ! is-t2-chip; then
    say "Installing $(c "$arch") bootloader in chroot"
    run root-chroot grub-install \
      --force --recheck --removable --skip-fs-probe \
      --target="$arch" \
      "${secure_params[@]}" \
      --efi-directory="/boot/efi" $NONVRAM \
      --boot-directory="/boot" \
      "$DISK" || true
  fi
done

if [ "$(sudo mokutil --sb-state | head -n1 | awk '{print $2}')" == 'enabled' ]; then
  say "Setting up SHIM Loader"
  {
    SHIM="$ROOT"/roles/global/shim
    KEYS="$ROOT"/roles/global/secure-keys
    EFI=/boot/efi/EFI

    run mv "$PREFIX/$EFI"/BOOT/{BOOTX64,grubx64}.efi
    run cp "$SHIM"/shimx64.efi "$PREFIX/$EFI"/BOOT/BOOTX64.efi
    run cp "$SHIM"/mmx64.efi "$PREFIX/$EFI"/BOOT/

    say "Signing bootloader and kernel"
    if ! is-signed "$PREFIX/$EFI"/BOOT/grubx64.efi; then
      run root-chroot "sbsign --key $KEYS/MOK.key --cert $KEYS/MOK.crt --output \
        $EFI/BOOT/grubx64.efi $EFI/BOOT/grubx64.efi"
    fi

    if ! is-signed "$PREFIX/$EFI"/arch/grubx64.efi; then
      run root-chroot "sbsign --key $KEYS/MOK.key --cert $KEYS/MOK.crt --output \
        $EFI/arch/grubx64.efi $EFI/arch/grubx64.efi"
    fi

    if ! is-signed "$PREFIX"/boot/vmlinuz-linux; then
      run root-chroot "sbsign --key $KEYS/MOK.key --cert $KEYS/MOK.crt --output \
      /boot/vmlinuz-linux /boot/vmlinuz-linux"
    fi

    say "Copying key to EFI Partition"
    run cp "$KEYS"/MOK.cer "$PREFIX"/boot/efi/ENROLL_THIS.cer
  }
fi

say "Configuring bootloaders"
{
  role="${client:-"$(jq -r '.role' /srv/secure/config.json)"}"

  if [[ $role =~ ^(client|server)$ ]]; then
    grub_cfg="/var/btrfs/@root/boot/grub/grub.cfg"
  else
    grub_cfg="$PREFIX/boot/grub/grub.cfg"
  fi

  if grep -q "MacBookPro8,2" "/sys/class/dmi/id/product_name"; then
    mbp_cli="i915.modeset=1 radeon.modeset=0"
  fi

  if is-t2-chip; then
    t2_params="intel_iommu=on iommu=pt pcie_ports=compat"
  fi

  write "$grub_cfg" "
insmod part_gpt
insmod iso9660

insmod all_video
insmod efi_gop
insmod efi_uga
insmod video_bochs
insmod video_cirrus

insmod font
insmod gfxterm
insmod png

terminal_input console
terminal_output gfxterm

# loadfont /@root/boot/grub/themes/TechLitAfrica/roboto-32.pf2
# loadfont /@root/boot/grub/themes/TechLitAfrica/fira-24.pf2

default=0
timeout=0
# theme=/@root/boot/grub/themes/TechLitAfrica/theme.txt

menuentry 'TechLit Desktop' --class artix {
  set gfxpayload=keep
  search --no-floppy --fs-uuid --set=root $root_uuid

  linux /@root/boot/vmlinuz-linux \\
    root=UUID=$root_uuid rootflags=subvol=@root init=/sbin/init tl-role=desktop \\
    ro rd.luks=0 rd.dm=0 add_efi_memmap \\
    loglevel=3 console=tty1 udev.log_level=3 vt.global_cursor_default=1 \\
    net.ifnames=0 vconsole.unicode=1 vconsole.keymap=us locale.LANG=en_US.UTF-8 \\
    $mbp_cli $t2_params

  initrd /@root/boot/initramfs-linux.img
}

menuentry 'Reboot' --class restart {
  reboot
}

menuentry 'Shutdown' --class shutdown {
  halt
}
"
}

# Unmount system and quiet exit hook
cleanup
cleanup() { :; }
say "Done."
