#!/bin/busybox sh
# shellcheck disable=SC1091

IN_CI="false"
LOG_PREFIX="[pmOS-rd]"

[ -e /hooks/10-verbose-initfs.sh ] && set -x

[ -e /hooks/05-ci.sh ] && IN_CI="true"

[ -e /etc/unudhcpd.conf ] && . /etc/unudhcpd.conf
. ./init_functions.sh
. /usr/share/misc/source_deviceinfo
[ -e /etc/os-release ] && . /etc/os-release
# provide a default for os-release's VERSION in case the file doesn't exist
VERSION="${VERSION:-unknown}"

# This is set during packaging and is used when triaging bug reports
INITRAMFS_PKG_VERSION="3.2.1-r0"

export PATH=/usr/bin:/bin:/usr/sbin:/sbin
/bin/busybox --install -s
/bin/busybox-extras --install -s

# Mount everything, set up logging, modules, mdev
mount_proc_sys_dev
setup_log
setup_firmware_path
# Run udev early, before splash, to make sure any relevant display drivers are
# loaded in time
setup_udev

if [ "$IN_CI" = "false" ]; then
	setup_framebuffer
	show_splash "Loading..."
fi

setup_dynamic_partitions "${deviceinfo_super_partitions:=}"

run_hooks /hooks

if [ "$IN_CI" = "true" ]; then
	echo "PMOS: CI tests done, disabling console and looping forever"
	dmesg -n 1
	fail_halt_boot
fi

setup_usb_network
start_unudhcpd

if grep -q "pmos.debug-shell" /proc/cmdline; then
	debug_shell
fi

check_keys

mount_subpartitions

wait_boot_partition
mount_boot_partition /boot
extract_initramfs_extra /boot/initramfs-extra
run_hooks /hooks-extra

# For testing the mass storage gadget log export function. We use a flag
# file on /boot so that we can test it on all devices as modifying the
# kernel cmdline is not always possible.
if [ -e /boot/.pmos_export_logs ]; then
	echo "PMOS: Exporting logs via mass storage gadget"
	show_splash "Exporting boot logs..."
	# Delete the flag so we don't soft-brick the device by always booting
	# to the log export mode.
	mount -o remount,rw /boot
	rm -f /boot/.pmos_export_logs
	fail_halt_boot
fi

wait_root_partition
delete_old_install_partition
resize_root_partition
unlock_root_partition
resize_root_filesystem
mount_root_partition

# Mount boot partition into sysroot, so we do not depend on /etc/fstab, as
# not all old installations have a proper /etc/fstab file. See #2800
umount /boot
mount_boot_partition /sysroot/boot "rw"

init="/sbin/init"
setup_bootchart2

# ProLinux Init
# /squishroot - squashfs rootfs
# /persistroot - overlayed persisant storage
# /tmproot - overlayed tmpfs
# /workdir - overlayfs workdir
# /oroot - target root

splash_error() {
    show_splash "ERROR: $1"
    sleep 5
    pkill pbsplash
    /bin/busybox sh
}

echo "Running ProLinux Init script..."
#  show_splash "Loading system configuration..."
pkill pbsplash

echo "-- Welcome to Sineware ProLinux 2 --"
modprobe squashfs || echo "Could not load squashfs module!"
modprobe overlay || echo "Could not load overlayfs module!"
echo "Mounting prolinux squashfs 'squishroot'"
mount -o remount,rw /sysroot

echo "----"
echo "Loading System Configuration..."
# read /sysroot/data/prolinux.toml for which squashfs to use
selected_root=$(awk -F "=" '/pl2.selected_root/ {print $2}' /sysroot/data/prolinux.toml | tr -d ' ' | tr -d "'")
locked_root=$(awk -F "=" '/pl2.locked_root/ {print $2}' /sysroot/data/prolinux.toml | tr -d ' ' | tr -d "'")
disable_kexec=$(awk -F "=" '/pl2.disable_kexec/ {print $2}' /sysroot/data/prolinux.toml | tr -d ' ' | tr -d "'")
echo "Selected Root: $selected_root"
echo "Locked Root: $locked_root"
echo "Disable Kexec: $disable_kexec"
echo "----"

mount -o loop /sysroot/prolinux_${selected_root}.squish /sysroot/squishroot 

# if pl2.stage2 is in the cmdline, OR if disable_kexec is true, we are in stage 2
if [ "$(cat /proc/cmdline | grep pl2.stage2)" != "" ] || [ "$disable_kexec" = "true" ]; then
    echo "Loaded stage 2 kernel!"

    # If /sysroot/data/.reset_persistroot exists, we need to reset the persistroot
    if [ -f /sysroot/data/.reset_persistroot ]; then
        echo "Resetting persistroot..."
        rm -rf /sysroot/persistroot/*
        rm -rf /sysroot/data/.reset_persistroot
    fi

    # we are booted into the stage 2 kernel.
    # if we are locked, we need to mount the locked rootfs
    mkdir -pv /sysroot/data/customization
    if [ "$locked_root" = "true" ]; then
        echo "Locked rootfs detected, mounting..."
        mkdir -pv /tmproot
        mount -t tmpfs tmpfs /tmproot
        mkdir -pv /tmproot/overlay
        mkdir -pv /tmproot/workdir
        mount -t overlay overlay -o lowerdir=/sysroot/data/customization:/sysroot/persistroot:/sysroot/squishroot,upperdir=/tmproot/overlay,workdir=/tmproot/workdir /sysroot/oroot || splash_error "Could not mount overlayfs!"
    else
        mount -t overlay overlay -o lowerdir=/sysroot/data/customization:/sysroot/squishroot,upperdir=/sysroot/persistroot,workdir=/sysroot/workdir /sysroot/oroot || splash_error "Could not mount overlayfs!"
    fi

    echo "Binding persistent directories into oroot"

    mount --bind /sysroot /sysroot/oroot/sineware
    mount --bind /sysroot/data/home /sysroot/oroot/home

    mkdir -pv /sysroot/oroot/lib/modules
    mount --bind /sysroot/squishroot/opt/device-support/$deviceinfo_codename/modules /sysroot/oroot/usr/lib/modules || splash_error "Could not mount kernel modules!"

    mkdir -pv /sysroot/oroot/lib/firmware
    mount --bind /sysroot/squishroot/opt/device-support/$deviceinfo_codename/firmware /sysroot/oroot/usr/lib/firmware || splash_error "Could not mount firmware!"

    # Podman container directories
    mkdir -pv /sysroot/data/containers
    mount --bind /sysroot/data/containers /sysroot/oroot/var/lib/containers

    # PMOS_BOOT to /sysroot/oroot/boot
    #mkdir -pv /sysroot/oroot/boot
    #mount /dev/disk/by-label/PMOS_BOOT /sysroot/oroot/boot || splash_error "Could not mount PMOS_BOOT!"

    echo $deviceinfo_codename > /sysroot/deviceinfo_codename

    ls -l /sysroot
    echo "----"
    #/bin/busybox sh

    ls -l /sysroot/oroot
    echo "Starting up..."
    
    show_splash "Starting up..."
else 
    echo "Loading stage 2 kernel (kexec) from /sysroot/squishroot/device-support/$deviceinfo_codename/..."
    cmdline=$(cat /proc/cmdline)

    # remove initcall_blacklist=* from cmdline
    cmdline=$(echo $cmdline | sed 's/initcall_blacklist=[^ ]*//g')
    cmdline=$(echo $cmdline | sed 's/modprobe.blacklist=[^ ]*//g')
    
    cmdline="$cmdline pl2.stage2"
    kexec -l /sysroot/squishroot/opt/device-support/$deviceinfo_codename/vmlinuz* --initrd=/sysroot/squishroot/opt/device-support/$deviceinfo_codename/initramfs --append="$cmdline"
    umount /sysroot/squishroot
    kexec -e

    # kexec failed
    splash_error "Could not kexec stage 2 kernel!"
fi

# Switch root
run_hooks /hooks-cleanup

echo "Switching root"

# Restore stdout and stderr to their original values if they
# were stashed
if [ -e "/proc/1/fd/3" ]; then
	exec 1>&3 2>&4
elif ! grep -q "pmos.debug-shell" /proc/cmdline; then
	echo "$LOG_PREFIX Disabling console output again (use 'pmos.debug-shell' to keep it enabled)"
	exec >/dev/null 2>&1
fi

# Make it clear that we're at the end of the initramfs
show_splash "Starting..."

# Re-enable kmsg ratelimiting (might have been disabled for logging)
echo ratelimit > /proc/sys/kernel/printk_devkmsg

killall mdev udevd syslogd 2>/dev/null

# Kill any getty shells that might be running
for pid in $(pidof sh); do
	if ! [ "$pid" = "1" ]; then
		kill -9 "$pid"
	fi
done

# shellcheck disable=SC2093
exec switch_root /sysroot/oroot "$init"

echo "$LOG_PREFIX ERROR: switch_root failed!" > /dev/kmsg
echo "$LOG_PREFIX Looping forever. Install and use the debug-shell hook to debug this." > /dev/kmsg
echo "$LOG_PREFIX For more information, see <https://postmarketos.org/debug-shell>" > /dev/kmsg
fail_halt_boot
