# -*- sh -*-
# vim:ft=sh:ts=8:sw=4:noet

AddConfigHandler VirtualboxOptions
AddConfigHelp "SuspendVirtualbox <boolean>" "This will run \"VBoxManage controlvm <VM> savestate\" for each running VM and restore state on resume."

VirtualboxSavestate() {
    local pid
    local user
    local vm
    local users=""

    for pid in `pidof VirtualBox`; do
	users="$users $(awk 'BEGIN {RS="\000";FS="="} ($1 == "USER"){print $2}' < /proc/$pid/environ)"
    done
    users=$(echo $users | tr ' ' '\n' | sort --unique)
    for user in $users; do
	for vm in $(su "$user" -c "VBoxManage -nologo list runningvms"); do
	    vecho 1 "Suspending vm $vm for user $user"
	    su "$user" -c "VBoxManage -nologo controlvm $vm savestate"
	    VIRTUALBOX_STOPPED="$VIRTUALBOX_STOPPED $user:$vm"
	done
    done

    # Failure is not USUALLY fatal, but storing VM state saves reasonable
    # amount of memory. I say "USUALLY" as I'm not sure if it is virtualbox
    # that causes some suspend-related bugs.
    return 0
}

VirtualboxRestorestate() {
    local vmtag
    local user
    local vm

    for vmtag in $VIRTUALBOX_STOPPED; do
	user=$(echo $vmtag | cut -d : -f 1)
	vm=$(echo $vmtag | cut -d : -f 2)
	vecho 1 "Restoring vm $vm for user $user"
	su "$user" -c "VBoxManage -nologo startvm $vm"
    done
    unset VIRTUALBOX_STOPPED
    
    return 0
}

VirtualboxOptions() {
    case $1 in
	suspendvirtualbox)
    	    if BoolIsOn "$1" "$2" && [ -z "$VIRTUALBOX_HOOKED" ] ; then
		AddSuspendHook 20 VirtualboxSavestate
		AddResumeHook 20 VirtualboxRestorestate
		VIRTUALBOX_HOOKED=1
		VIRTUALBOX_STOPPED=""
	    fi
	    return 0
	    ;;
    esac
    return 1
}

