#!/sbin/busybox sh
#
# tiny init script

panic() {
    printf "panic >> %s\n" "$@" && sh
}

# parse_cmdline() {
# TODO parse /proc/cmdline
#}

mnt_pseudofs() {
    # mount pseudofs's
    mount -t proc none /proc
    mount -t sysfs none /sys
    mount -t devtmpfs none /dev
}

use_mdev() {
    # setup mdev
    if [ -e /proc/sys/kernel/hotplug ]; then
	printf /sbin/mdev >/proc/sys/kernel/hotplug
    else
	uevent mdev &
    fi

    # trigger mdev
    mdev -s

    # trigger uevent for usb devices
    for u in /sys/bus/usb/devices/*; do
	case ${u##*/} in
	    [0-9]*-[0-9]*)
	    printf add > "${u}/uevent"
            ;;
        esac
    done

    # load drivers
    find /sys -name "modalias" -type f -exec cat "{}" + | sort -u | xargs modprobe -ba
}

use_mdevd() {
    # setup mdevd
    mdevd &
    # trigger uevents
    mdevd-coldplug

    # TODO investigate this
    # avoid race condition
    sleep 1.5
}

use_udev() {
    # setup udev
    udevd --daemon
    udevadm trigger --action=add --type=subsystems
    udevadm trigger --action=add --type=devices
    udevadm settle
}

unlock_luks() {
    # find device of luks root
    luks_root="$(findfs $luks_root)"

    # TODO improve mapper name ( crypttab or config option )
    # unlock luks container
    cryptsetup $luks_args luksOpen "$luks_root" luks_root || panic "failed to unlock luks container"
}

trigger_lvm() {
    # manually trigger LVM if udev disabled
    lvm vgchange --sysinit -a y
}

mnt_rootfs() {
    # merge mount flags
    [ -n "$root_args" ] && mount_args="$root_args"
    [ -n "$root_type" ] && mount_args="$mount_args -t $root_type"

    # mount rootfs    
    mount $mount_args "$root" /mnt/root || panic "failed to mount rootfs"
}

cleanup() {
    # clean up
    [ "$devmgr" = "mdev" ] && { printf "" >/proc/sys/kernel/hotplug || killall uevent; } >/dev/null 2>&1
    [ "$devmgr" = "mdevd" ] && killall mdevd
    [ "$devmgr" = "udev" ] && udevadm control --exit
    umount /dev /sys /proc
}

boot_system() {
    # boot system
    exec switch_root /mnt/root /sbin/init || panic "failed to boot system"
}

# install busybox
/sbin/busybox --install -s

# check config
if [ -e /config ]; then
    . /config
else
    panic "config doesn't exists"
fi

if [ "$debug" = 1 ]; then
    # debug shell commands 
    set -x
else
    # silence is golden
    printf 0 >/proc/sys/kernel/printk
fi

#parse_cmdline
mnt_pseudofs

case "$devmgr" in
    mdev) use_mdev ;;
    mdevd) use_mdevd ;;
    udev) use_udev ;;
    *) panic "devmgr option broken" ;;
esac

# TODO handle situations when LUKS on LVM
[ "$use_luks" = 1 ] && unlock_luks
[ "$use_lvm" = 1 ] && [ "$devmgr" != "udev" ] && trigger_lvm
mnt_rootfs
cleanup
boot_system