#!/bin/sh

# Debugging
debug() {
	rm /tmp/swapset
	exec  &> /tmp/swapset
}

# Tuning
compcache_size=65536  # Size of cache in KB
priority_compcache=15
priority_external=10
priority_internal=0
compcache_timeout=10  # Timeout for device node to be ready in seconds

# Constants
compcache_module=/lib/modules/current/ramzswap.ko
device_internal=mmcblk0
device_external=mmcblk1
device_compcache=ramzswap0

# Calculated
swapdrivelist_internal=$(sfdisk -lnd | grep Id=82 | awk "/$device_internal/ {print \$1}")
swapdrivelist_external=$(sfdisk -lnd | grep Id=82 | awk "/$device_external/ {print \$1}")
if [ -n "$(swapon 2>&1 | grep "\-p")" ]
then
	priority_available=true
fi

# If priority support is available, use it
if [ "$priority_available" ]
then
	priority_compcache="-p $priority_compcache "
        priority_external="-p $priority_external "
        priority_internal="-p $priority_internal "
fi

enable_compcache() {
	# Compcache first - we want stuff to get bumped here.
	if [ -e "$compcache_module" ]
	then
		if [ "$priority_available" ]
		then
			priority=$priority_compcache
		fi

		insmod $compcache_module disksize_kb=$compcache_size
		compcache_succeeded=$?
		if [ "$compcache_succeeded" ]
		then
			start_wait=$(date +%s)
			while [ ! -s /dev/$device_compcache -a $(($(date +%s) - $start_wait)) -lt $compcache_timeout ]
			do
				#printf "Waiting %ds for compcache to be ready... \r" $(($compcache_timeout - ($(date +%s) - $start_wait)))
				echo -n .
			done
			echo
			swapon $priority/dev/$device_compcache
		fi
	fi
}

disable_external() {
        # If we have at least one other type of swap, disable the external swap
        if [ "$compcache_succeeded" -o -n "$swapdrivelist_internal" ]
        then
                # Turn off the external swap
                for swapdrive in $swapdrivelist_external
                do
                        swapoff $swapdrive
                done
	else
		echo Unable to disable external swap - No other swap active
		exit -1
        fi
}

enable_external() {
	# Turn on SD swap first
	for swapdrive in $swapdrivelist_external
	do
		if [ "$priority_available" ]
		then
			priority=$priority_external
		fi
                if [ -z "$(cat /proc/swaps | grep $swapdrive)" ]
		then
 			swapon $priority$swapdrive
		fi
	done
}

disable_internal() {
	# If we have at least one other type of swap, disable the internal swap
	if [ "$compcache_succeeded" -o -n "$swapdrivelist_external" ]
	then
		# Turn off the internal swap
		for swapdrive in $swapdrivelist_internal
		do
	        	swapoff $swapdrive
		done
        else
                echo Unable to disable internal swap - No other swap active
                exit -1
	fi
}

enable_internal() {
        if [ -n "$swapdrivelist_internal" ]
        then
                # Turn on internal swap
                for swapdrive in $swapdrivelist_internal
                do
                        if [ "$priority_available" ]
                        then
                                priority=$priority_internal
                        fi
			if [ -z "$(cat /proc/swaps | grep $swapdrive)" ]
			then
	                        swapon $priority$swapdrive
			fi
                done
        fi
}


case "$1" in
	startup)
	        if [ true ]
	        then
			debug
 		fi

		enable_compcache
		enable_external
		# Disable the internal swap to bump things into the preferred swap
		disable_internal
		enable_internal
	;;
        unmount)
		enable_internal
                disable_external
        ;;
        mount)
                enable_external
		# Disable the internal swap to bump things into the preferred swap
                disable_internal
		enable_internal
        ;;

  *)
        echo "Usage: /usr/sbin/swapset {startup|unmount|mount}"
        exit 1
esac

exit 0

