#!/bin/sh

PATH=/bin:/usr/bin:/sbin:/usr/sbin
SYSTEM_RECOVERY="/usr/libexec/initrd-recovery/system-recovery"
SYSTEM_RECOVERY_GUI="/usr/bin/system-recovery_gui"

MOUNT="/usr/bin/mount"
BLKID="/usr/sbin/blkid"
REBOOT="/usr/libexec/initrd-recovery/minireboot"
SYNC="/usr/bin/sync"
UMOUNT="/usr/bin/umount"
CUT="/usr/bin/cut"
LS="/usr/bin/ls"
MKDIR="/usr/bin/mkdir"
RMDIR="/usr/bin/rmdir"
TR="/usr/bin/tr"

FAKE_ROOT="/system-ro"
HAL_MNT=hal
#------------------------------------------------
#       mount_usb_partitions
#------------------------------------------------
USB_MOUNTPOINT_PREFIX=/tmp/USBDrive
mount_usb_partitions() {
    echo "mount USB partitions"
    DEVICE_TYPE_LIST=(
        ext4
        vfat
    )

    LAST_MOUNTED_DEVICE=""
    for DEVICE_TYPE in ${DEVICE_TYPE_LIST[@]}
    do
        DEVICES=""
        for ((i=0; i<10; i++))
        do
            DEVICES=$("$BLKID" /dev/sd* -t TYPE="${DEVICE_TYPE}" -o device)
            if [ ! -z "${DEVICES}" ]
            then
                for DEVICE in ${DEVICES}
                do
                    USB_MOUNTPOINT_INDEX=$(echo ${DEVICE} | "$CUT" -b 8- | "$TR" '[:lower:]' '[:upper:]')
                    USB_MOUNTPOINT=${USB_MOUNTPOINT_PREFIX}${USB_MOUNTPOINT_INDEX}
                    "$MKDIR" -p ${USB_MOUNTPOINT}
                    "$MOUNT" -t ${DEVICE_TYPE} ${DEVICE} ${USB_MOUNTPOINT}

                    LAST_MOUNTED_DEVICE=${DEVICE}
                done
                break
            fi

            sleep 1
        done
    done

    if [ -z "${LAST_MOUNTED_DEVICE}" ]
    then
        echo "WARNING : USB not mounted"
    fi
}

#------------------------------------------------
#       umount_usb_partitions
#------------------------------------------------
umount_usb_partitions() {
    echo "umount USB partitions"
    USB_MOUNTPOINTS=$("$LS" -d ${USB_MOUNTPOINT_PREFIX}*)
    for USB_MOUNTPOINT in ${USB_MOUNTPOINTS}
    do
        "$UMOUNT" ${USB_MOUNTPOINT}
        "$RMDIR" ${USB_MOUNTPOINT}
    done
}

#------------------------------------------------
#       do_reboot
#------------------------------------------------
do_reboot() {
    echo "Reboot"
    "$SYNC"
    "$REBOOT"
    while [ 1 ]
    do
        sleep 1
        echo "."
    done
}

#------------------------------------------------
#       get partition id
#------------------------------------------------
get_partition_id() {
    P_SLOT=$([[ $(</proc/cmdline) =~ partition_ab=([ab]) ]]; echo ${BASH_REMATCH[1]})
    P_SUFFIX=""

    if [ "${P_SLOT}" != "" ]; then
        P_SUFFIX="_${P_SLOT}"
        echo "Using A/B slot: ${P_SLOT}"
    fi

    if [ x$PART_ROOTFS = "x" ]
    then
        PART_ROOTFS=`/sbin/blkid -t PARTLABEL=rootfs${P_SUFFIX} -o device -l`
    fi
    if [ x$PART_ROOTFS = "x" ]
    then
        PART_ROOTFS=`/sbin/blkid -L rootfs`
    fi

    PART_SYSTEM_DATA=`/sbin/blkid -t PARTLABEL=system-data -o device -l`
    if [ x$PART_SYSTEM_DATA = "x" ]
    then
        PART_SYSTEM_DATA=`/sbin/blkid -L system-data`
    fi

    PART_RAMDISK=`/sbin/blkid -t PARTLABEL=ramdisk${P_SUFFIX} -o device -l`
    if [ x$PART_RAMDISK = "x" ]
    then
        PART_RAMDISK=`/sbin/blkid -L ramdisk`
    fi

    if [ x$HALFS = "x" ]
    then
        PART_HAL=`/sbin/blkid -t PARTLABEL=hal${P_SUFFIX} -o device -l`
    fi
    if [ x$PART_HAL = "x" ]
    then
        PART_HAL=`/sbin/blkid -L hal`
    fi

    PART_USER=$("$BLKID" --match-token PARTLABEL=user -o device -l || "$BLKID" --match-token LABEL=user -o device -l)
}

#------------------------------------------------
#       mount_rootfs
#------------------------------------------------
mount_rootfs()
{
	/usr/bin/verityctl create rootfs "${PART_ROOTFS}" "${FAKE_ROOT}"
        case $? in
            0)
                echo "verifyboot: disabled"
                # do nothing
                ;;
            1)
                echo "verityboot: enabled";
                return
                ;;
            2)
                echo "verifyboot: enabled but corrupted"
		do_reboot
                ;;
            3)
                echo "verifyboot: disabling"
                ;;
        esac
	"$MOUNT" -o ro "${PART_ROOTFS}" "${FAKE_ROOT}"
}

#------------------------------------------------
#       mount_partitions
#------------------------------------------------
mount_partitions() {
    get_partition_id

    mount_rootfs
    if [ ! "z${PART_HAL}" = "z" ]; then
        "$MOUNT" -o ro "${PART_HAL}" "${FAKE_ROOT}/${HAL_MNT}"
    fi
    "$MOUNT" -t proc none ${FAKE_ROOT}/proc
    "$MOUNT" -t sysfs none ${FAKE_ROOT}/sys
    "$MOUNT" -t devtmpfs devtmpfs ${FAKE_ROOT}/dev
    "$MOUNT" -t devpts devpts ${FAKE_ROOT}/dev/pts
    "$MOUNT" -t tmpfs tmpfs ${FAKE_ROOT}/tmp
}

#------------------------------------------------
#       run_recovery_target
#------------------------------------------------
run_recovery_target() {
    cd ${FAKE_ROOT}
    exec /bin/chroot . /usr/lib/systemd/systemd --unit=recovery.target $@
}

#------------------------------------------------
#       system-recovery initrc
#------------------------------------------------
echo "Starting system recovery."
mount_usb_partitions

# For debugging - It should be deleted on Release
/sbin/agetty -l /bin/sh -n --keep-baud 115200,38400,9600 console linux &

[ -x "${SYSTEM_RECOVERY_GUI}" ] && "${SYSTEM_RECOVERY_GUI}" &
[ -x "${SYSTEM_RECOVERY}" ] && "${SYSTEM_RECOVERY}"

umount_usb_partitions
mount_partitions
run_recovery_target
do_reboot
