#!/bin/sh

usage() {
	echo "$0 [-s [-e sudo|doas]] server"
	exit 0
}


while getopts nse: arg; do
	case ${arg} in
		n) SIMULATE=1 ;;
		s) SUDO=1 ;;
		e) SUDO_BIN="${OPTARG}" ;;
		*) usage ;;
	esac
done
shift $((OPTIND - 1))

# allow to use a privilege escalation program
if [ "$SUDO" -eq 1 ]
then
	# defaulting to sudo
	if [ -z "$SUDO_BIN" ]
	then
		SUDO_BIN=sudo
	fi
	EXEC="$SUDO_BIN"
else
	EXEC=""
fi

# check if host exists
if [ "$#" -ne 1 ]; then
	usage
else
	HOSTNAME=$(ssh "$1" "${EXEC} uname -n")
	if [ "$?" -ne 0 ]; then
		echo "Error while ssh ${1}"
		exit 2
	fi
fi

# $1 = directory name
# $2 = remote server
copy_files() {
	# -l = keep symlink / -D = special device
	if [ -d "${1}" ]
	then
		LIST=$(mktemp /tmp/drist-rsync.XXXXXXXXXX)
		if [ -f "$LIST" ]
		then
			printf 'Copying files from folder "%s":\n' "$1"
			find "${1}"/ -type f | cut -d '/' -f 2- | tee "${LIST}" | sed 's/^/	\//'
			if [ "$SIMULATE" -ne 1 ]
			then
				rsync --rsync-path="${EXEC} rsync" -lD --files-from="${LIST}" "${1}/" "${2}":/
			fi
			rm "$LIST"
		fi
	fi
}

# $1 = script filename
# $2 = remote server
remote_script() {
	if [ -f "${1}" ]
	then
		printf 'Executing file "%s":\n' "$1"
		if [ "$SIMULATE" -ne 1 ]
		then
			ssh "${2}" "DRIST=$(mktemp /tmp/drist.XXXXXXXXXXXX) &&
			    cat - > \$DRIST &&
			    chmod u+x \$DRIST &&
			    ${EXEC} \$DRIST ;
			    rm \$DRIST" < "$1"
		fi
	fi
}

# $1 = directory name
# $2 = remote server
# it uses rm -v which is not POSIX compliant but most systems have it
delete_files() {
	if [ -d "${1}" ]
	then
		LIST=$(mktemp /tmp/drist-rsync.XXXXXXXXXX)
		if [ -f "$LIST" ]
		then
			printf 'Removing files from folder "%s":\n' "$1" 
			find "$1" -type f | sed 's/"/\\&/' | \
				awk -v path="${1}" '{ printf "\"%s\" ",substr($0,length(path)+1)}' | \
				tee "${LIST}" | sed 's/^/	/'
			printf '\n' # add a new line

			if [ "$SIMULATE" -ne 1 ]
			then
				test -s "$LIST" && ssh "$2" "${EXEC} rm $(cat $LIST)"
			fi
			rm $LIST
		fi
	fi
}


copy_files "files" "$1"
copy_files "files-${HOSTNAME}" "$1"
remote_script "script" "$1"
remote_script "script-${HOSTNAME}" "$1"
delete_files "absent" "$1"
delete_files "absent-${HOSTNAME}" "$1"
