#!/bin/sh

#
# ZFS subcommand wrapper
VER="1.1-01"
#
# ZFS is very sysadmin-friendly by itself. With this script,
# administration of ZFS becomes even more pleasant.
#
AUTHOR="kkatarn@sleepgate.ru, 2016"
#
# TODO: documentation.
#

ECHO=""
PREPEND_DATE=""
DATE_HMS="Y"

move_up() {
	local _dir=$1 _up _last
	_last=$(basename ${_dir})
	_up=$(echo ${_dir} | sed "s/\/${_last}//")
	[ -n "${_up}" ] && echo -n ${_up} || echo -n "/"
}

guess_dataset() {
	local _fs _dset _where=$(realpath $1 2>/dev/null)
	_dset=${_where}
	[ -z "${_dset}" ] && return 1
	while true; do
		_fs=$(mount | grep " ${_dset} " | awk '{print $1;}' 2>/dev/null)
		if [ -n "${_fs}" ]; then
			echo -n ${_fs}
			return 0
		fi
		if [ "${_dset}" = "/" ]; then
			echo ${_where} | sed -e 's/^\///'
			return 1
		fi
		_dset=$(move_up "${_dset}")
	done
}

_me=$(basename $0)
_argv=""
_argc=0
_dset=$(guess_dataset $(pwd))
_snap=""
_subargs=""

usage() {
	echo "ZFS snapshot/rollback/list/destroy/send wrapper ver. ${VER}"
	echo "${AUTHOR}"
	echo "Usage: ${_me} [--help] [--echo] [--date|--date-hms] [snapshot-name] [-- <subcommand arguments>]"
	echo "	--help (-h): print this message;"
	echo "	--echo: just echo zfs command to be issued;"
	echo "	--date (-d): prepend Year-Month-Day to the snapshot name;"
	echo -n "	--date-hms (-dd): prepend Y-M-D-Hour-Min-Sec"
	if [ "${_me}" == "zlist" -o "${_me}" == "lss" ]; then
		echo ";"
	else
		echo " (default)."
	fi
}

for _arg in $@; do
	if [ -n "${_subargs}" ]; then
		_subargs="${_subargs}${_arg} "
		continue
	fi
	case ${_arg} in
		'--echo')
			ECHO="Y"
			;;
		'-h'|'--help')
			usage
			exit 0
			;;
		'-d'|'--date')
			PREPEND_DATE="Y"
			DATE_HMS=""
			;;
		'-dd'|'--date-hms')
			PREPEND_DATE="Y"
			;;
		'--')
			_subargs=" "
			;;
		*)
			_argc=$((${_argc}+1))
			[ -z "${_argv}" ] && _argv="${_arg}" || _argv="${_argv} ${_arg}"
			;;
	esac
done

case ${_argc} in
	0)
		_snap=""
		PREPEND_DATE="Y"
		;;
	1)
		_snap=${_argv}
		;;
	*)
		usage
		exit 1
		;;
esac

if [ -n "${PREPEND_DATE}" -a "${_me}" != "zlist" -a "${_me}" != "lss" ]; then
	[ -n "${_snap}" ] && _snap="-${_snap}"
	[ -n "${DATE_HMS}" ] &&	\
		_date=$(date "+%Y-%m-%d-%H-%M-%S") || \
		_date=$(date "+%Y-%m-%d")
	_snap="${_date}${_snap}"
fi

many_mees() {
	local _mees _me=$(realpath $0)
	local _path=$(move_up ${_me})
	if [ -e "${_path}/znap" ]; then
		echo "Error: \"${_path}/znap\" already exists!"
		exit 1
	fi
	mv "${_me}" "${_path}/znap" || exit 1
	_me="${_path}/znap"
	for _mees in zdel zroll zend zlist lss; do
		[ -e "${_path}/${_mees}" ] && \
			echo "Warning: \"${_path}/${_mees}\" already exists!" || \
			ln -s "${_me}" "${_path}/${_mees}"
	done
}

case "${_me}" in
	"znap")
		_subcmd="snapshot"
		;;
	"zdel")
		_subcmd="destroy"
		;;
	"zroll")
		_subcmd="rollback"
		;;
	"zend")
		_subcmd="send"
		;;
	"zlist")
		[ ${_argc} -eq 0 ] && _subcmd="list -r" || _subcmd="list"
		;;
	"lss")
		[ ${_argc} -eq 0 ] && _subcmd="list -r" || _subcmd="list"
		_subargs="${_subargs} -t snapshot "
		;;
	*)
		echo "${_me}: i don't know subcommand for my name \"${_me}\", thus i'm exploding."
		many_mees
		exit 0
		;;
esac

[ -n "${_snap}" ] && _snap="@${_snap}"

CMD="zfs ${_subcmd} ${_subargs} ${_dset}${_snap}"

[ -z "$ECHO" ] && $CMD || echo $CMD
