#!/bin/bash
rescue_shell() {
    echo "Something went wrong. ProLinux failed to boot. Dropping to an emergency shell..."
    sh </dev/ttyS0 >/dev/ttyS0 2>&1 &
    exec sh
}
function cmdline() {
    local value
    value=" $(cat /proc/cmdline) "
    value="${value##* ${1}=}"
    value="${value%% *}"
    [ "${value}" != "" ] && echo "${value}"

}

clear
echo "* Sineware ProLinux Is Starting Up (Early Boot Environment) *"

mount -t proc none /proc
mount -t sysfs none /sys

echo "Loading device modules... (Coldplugging Devices)"
find /sys/devices -name modalias -type f -print0 | xargs -0 sort -u | xargs /sbin/modprobe -ab

echo "Populating /dev/"
mount -t devtmpfs none /dev

echo "Displaying bootsplash..."
#clear
DEVICE=$(cmdline prolinux_device)
if [[ "$DEVICE" == "pinephone" ]]; then
  fbsplash -s bootsplash-pinephone.ppm
else
  fbsplash -s bootsplash.ppm
fi

#trap 'rescue_shell' ERR

echo "Starting LVM..."
VG_NAME="ProLinuxVG"
lvchange -a y ${VG_NAME}  || rescue_shell

# Todo if running from ro boot firmware on mobile, kexec into the new kernel+initramfs on LVM
# on x86/PC, GRUB loads kernel+init directly from the root lvol, but on mobile the kernel+initramfs exists on a readonly boot partition,
# so we need to load the root lvol here and switch to the updated kernel there.

BOOT_STYLE=UNSET
BOOT_STYLE=$(cmdline bootstyle)
ROOT_DEV=$(cmdline root)

echo "Booting from device ${ROOT_DEV}"
if [[ "$BOOT_STYLE" = "live" ]]; then
  echo "Boot style is live."
  mount ${ROOT_DEV} /mnt/root || rescue_shell

  mkdir /mnt/live/rom
  mkdir /mnt/live/overlay

  mount -t tmpfs tmpfs /mnt/live/overlay
  mkdir /mnt/live/overlay/fs
  mkdir /mnt/live/overlay/work

  mount /mnt/root/squashfs.img /mnt/live/rom || rescue_shell

  mount -t overlay overlay -o lowerdir=/mnt/live/rom,upperdir=/mnt/live/overlay/fs,workdir=/mnt/live/overlay/work /mnt/live
  mkdir /mnt/live/system
  mount ${ROOT_DEV} /mnt/live/system

  # unmount, switch_root
  umount /proc
  umount /sys

  fbsplash -s bootsplash.ppm

  # Boot the real thing
  exec switch_root /mnt/live /usr/lib/systemd/systemd || rescue_shell
elif [[ "$BOOT_STYLE" = "system" ]]
then
  echo "Boot style is system."
  # Mount logical volumes
  # /mnt/config = config lvol
  # /mnt/data = data lvol (r/w)
  # /mnt/grub = grub lvol
  # /mnt/root = squashfs r/o root
  mkdir -pv /mnt/root /mnt/grub /mnt/config /mnt/data
  mount /dev/${VG_NAME}/lvol_root_a /mnt/root || rescue_shell # todo a/b scheme
  mount -o ro /dev/${VG_NAME}/lvol_grub /mnt/grub
  mount /dev/${VG_NAME}/lvol_config /mnt/config
  mount /dev/${VG_NAME}/lvol_data /mnt/data

  echo "Loading system configuration file..."
  # Load prolinux.ini from config lvol
  source /mnt/config/prolinux.ini

  # Prepare Directories
  mkdir -pv /mnt/data/system /mnt/data/system/root_home /mnt/data/system/overlay/upper /mnt/data/system/overlay/work

  # Enable development persistence overlay if enabled
  SWITCHROOT_DIR=/mnt/root
  if [[ "$DevelopmentOverlay" == "true" ]]; then
    echo "Enabling Development Persistence Overlay..."
    # /mnt/live = overlayfs mount (lower + upper)
    mkdir -pv /mnt/live
    mount -t overlay overlay -o lowerdir=/mnt/root,upperdir=/mnt/data/system/overlay/upper,workdir=/mnt/data/system/overlay/work /mnt/live || rescue_shell
    SWITCHROOT_DIR=/mnt/live
  else
    # Directories in RAM (rw, no saving)
    mount -t tmpfs tmpfs ${SWITCHROOT_DIR}/run
    mount -t tmpfs tmpfs ${SWITCHROOT_DIR}/var
  fi

  # Bind mount logical volumes into root
  mount --bind /mnt/data ${SWITCHROOT_DIR}/data
  mount --bind /mnt/config ${SWITCHROOT_DIR}/config
  mount --bind /mnt/grub ${SWITCHROOT_DIR}/boot/grub
  mount --bind /mnt/data/system/root_home ${SWITCHROOT_DIR}/root

  if [[ "$DEVICE" == "pinephone" ]]; then
    fbsplash -s bootsplash-pinephone.ppm
  else
    fbsplash -s bootsplash.ppm
  fi

  # clean up, switch_root
  umount /proc
  umount /sys
  exec switch_root ${SWITCHROOT_DIR} /usr/lib/systemd/systemd || rescue_shell
else
  echo "Error: unknown or not set boot style: '${BOOT_STYLE}'"
  rescue_shell
fi