#!/bin/sh

# Setup iohyve
__setup() {
	shift 1
	local args="$@"
	local poolval
	local kmodval
	local netval

	for arg in $args; do
		local prop="$(echo $arg | cut -d '=' -f1)"
		local val="$(echo $arg | cut -d '=' -f2)"
		if [ $prop = "pool" ]; then
			poolval=$val
		elif [ $prop = "kmod" ]; then
			kmodval=$val
		elif [ $prop = "net" ]; then
			netval=$val
		fi
		
	done
	
	# Run commands in correct order, so that the kernel modules are loaded
	# before the network is setup
	if [ -n "$poolval" ]; then
		__setup_pool $poolval
	fi
	if [ -n "$kmodval" ]; then
		__load_kernel_modules $kmodval
	fi
	if [ -n "$netval" ]; then
		__setup_network $netval
	fi
}

__setup_pool() {
	local pool="$1"
	if ! zfs list ${pool}/iohyve > /dev/null 2>&1; then
		echo "Setting up iohyve pool..."
		zfs create $pool/iohyve
		# iohyve is already setup on a pool
		if [ -d /iohyve/ISO ]; then
			echo "Secondary pool set up..."
			zfs set mountpoint="/iohyve/$pool" $pool/iohyve
			# iohyve is not set up yet
		else
			zfs set mountpoint="/iohyve" $pool/iohyve
			zfs create $pool/iohyve/ISO
			zfs create $pool/iohyve/Firmware
		fi
	else
		echo "iohyve already exists on $pool"
	fi
	# Checks to see if on FreeNAS
	# The web UI references this file to display the version
	if [ -e /etc/version ]; then
		local OS=$( cat /etc/version | cut -d - -f1 )
		if [ "$OS" = "FreeNAS" ]; then
			__setup_freenas $val
		fi
	fi
}

__setup_freenas() {
	local val=$1
	echo "On FreeNAS installation."
	echo "Checking for symbolic link to /iohyve from /mnt/iohyve..."
	if [ -d /mnt/iohyve ]; then
		if [ ! -e /iohyve ]; then
			ln -s /mnt/iohyve /iohyve
			if [ -L /iohyve ]; then
				echo "Symbolic link to /iohyve from /mnt/iohyve successfully created."
			else
				echo "Failed to create symbolic link."
				echo "Please manually do so by running the following as root:"
				echo "# ln -s /mnt/iohyve /iohyve"
			fi
		elif [ -L /iohyve ]; then
			echo "Symbolic link to /iohyve already exists."
		fi
	elif [ "$val" = "freenas-boot" ] && [ -d /iohyve ]; then
		echo "Symbolic link not needed. /iohyve exists."
		echo "iohyve is installed on the freenas-boot pool."
		echo "This is not recommended configuration."
	else
		echo "iohyve does not seem to be setup."
	fi
}

__load_kernel_modules() {
	local val=$1
	if [ $val = "1" ]; then
		echo "Loading kernel modules..."
		local modulelist
		if ! $(kldstat -q -m vmm); then
			modulelist="$modulelist vmm"
		fi
		if ! $(kldstat -q -m nmdm); then
			modulelist="$modulelist nmdm"
		fi
		if ! $(kldstat -q -m if_bridge); then
			modulelist="$modulelist if_bridge"
		fi
		if ! $(kldstat -q -m if_tap); then
			modulelist="$modulelist if_tap"
		fi
		# Load all modules together
		if [ "$modulelist" ]; then
			kldload $modulelist
		fi
	elif [ $val = "0" ]; then
		echo "Unloading kernel modules..."
		local modulelist
		if $(kldstat -q -m vmm); then
			modulelist="$modulelist vmm"
		fi
		if $(kldstat -q -m nmdm); then
			modulelist="$modulelist nmdm"
		fi
		if $(kldstat -q -m if_bridge); then
			modulelist="$modulelist if_bridge"
		fi
		if $(kldstat -q -m if_tap); then
			modulelist="$modulelist if_tap"
		fi
		# Unload all modules together
		if [ "$modulelist" ]; then
			kldunload $modulelist
		fi
	else
		echo "Improper syntax"
		echo "kmod=1 to load modules"
		echo "kmod=0 to unload modules"
	fi
}

__setup_network() {
	local iface=$1
	local bridgeif="$('ifconfig' -l | grep -F "bridge0" | cut -c1)"
	if [ -z $bridgeif ]; then
		echo "Setting up bridge0 on $iface..."
		if ! sysctl net.link.tap.up_on_open=1 > /dev/null 2>&1; then
			echo "cannot set 'net.link.tap.up_on_open': is if_tap loaded?"
		fi
		ifconfig bridge0 create descr "iohyve-bridge" addm $iface up
	else
		echo "bridge0 is already enabled on this machine..."
		local sysctlexist
		if ! sysctlexist="$(sysctl -n net.link.tap.up_on_open 2> /dev/null)"; then
			echo "cannot set 'net.link.tap.up_on_open': is if_tap loaded?"
			return 1
		fi

		if [ $sysctlexist = "0" ]; then
			echo "Setting up correct sysctl value..."
			sysctl net.link.tap.up_on_open=1
		else
			echo "sysctl already setup properly as well..."
		fi
	fi
}
