#!/bin/sh -


_command="${0##*/}"
_copy='0'
_exit_status='0'
if which jbroot 2>>/dev/null 1>>/dev/null; then
	_root_path='/rootfs'
	_jb_root_path="$(jbroot | sed 's#\/$##' | sed 's#^\/var#/private/var#')"
else
	#_root_path=''
	_jb_root_path="$(readlink -f '/var/jb')"
fi
_p_file="${_jb_root_path}/var/mobile/Library/Preferences/com.nan.auto-bindfs.plist"
_mount_to="$(plutil -key 'root' "${_jb_root_path}/var/mobile/Library/Preferences/com.nan.auto-bindfs.plist" 2>&1)"
if echo "${_mount_to}" | grep -q '^Error: ' ; then
	_mount_to="${_jb_root_path}/bindfs"
else
	case "${_mount_to}" in
		/rootfs*)
			_mount_to="$(readlink -f "$(echo "${_mount_to}" | sed 's#\/$##')" | sed 's#^\/rootfs##')"
			;;
		/*)
			if [ -z "${_root_path}" ]; then
				_mount_to="$(readlink -f "$(echo "${_mount_to}" | sed 's#\/$##')" | sed 's#^\/rootfs##')"
			else
				_mount_to="$(readlink -f "$(echo "/rootfs${_mount_to}" | sed 's#\/$##')" | sed 's#^\/rootfs##')"
			fi
			;;
		.jbroot|.jbroot/*)
			if [ -z "${_root_path}" ]; then
				_mount_to="$(readlink -f "$(echo "${_mount_to}" | sed "s#^.jbroot#${_jb_root_path}#" | sed 's#\/$##')")"
			else
				_mount_to="${_jb_root_path}$(readlink -f "$(echo "${_mount_to}" | sed "s#^.jbroot#${_jb_root_path}#" | sed 's#\/$##')")"
			fi
			;;
	esac
fi

_print_help(){
	echo "Usage: ${_command} [OPTIONS...] [PATH...]
	-h		Print this help 
	-l		print folder that will be mounted the next jailbreak
	-s		automatically mount the folder on the next jailbreak (empty when empty)
	-u		unmount folder that has been mounted as bindfs
	--copy		force a copy of all files within the original folder, even if they already exist
	--skip-copy	skip the copy check, even if there are no files in the destination

Example:
	${_command} \"/System/Library/Fonts\"
	${_command} \"/System/Library/Fonts\" \"/System/Library/ThermalMonitor\"
	${_command} -l
	${_command} -s \"/System/Library/Fonts\"
	${_command} -s \"/System/Library/Fonts\" \"/System/Library/ThermalMonitor\"
	${_command} -s
	${_command} -u \"/System/Library/Fonts\"
	${_command} -u \"/System/Library/Fonts\" \"/System/Library/ThermalMonitor\"
	${_command} --copy \"/System/Library/Fonts\"
	${_command} --skip-copy \"/System/Library/Fonts\"

Tips:
	\"-s\" will overwrite the configuration file set by the previous \"-s\" every time it is run
	\"--copy\" and \"--skip-copy\" only take effect when manually mounted and do not apply to automatic mountings"
}

_do(){
	_aaa="$("${_jb_root_path}/usr/libexec/mount_bindfs/jbctl-bindfs" "${1}" "${2}" "${3}" 2>&1)"
	_exit_status="$((_exit_status+$?))"
	if [ -z "${_aaa}" ]; then
		echo "status: Success"
	else
		echo "status: Failure"
		echo "Log: ${_aaa#*: }"
	fi
	unset _aaa
}

if [ "${#}" = '0' ]; then
	_print_help
	exit 1
fi
if ! id -u | grep -q '^0$'; then
	exec sudo "${0}" "$@"
	exit 0
fi
rm -rf "${_jb_root_path}/.bindfs"
ln -sf "${_mount_to}" "${_jb_root_path}/.bindfs"
while [ "${#}" -gt '0' ]; do
	case "${1}" in
		-h)
			_print_help
			exit 0
		;;
		--copy)
			_copy='1'
			shift 1
		;;
		--skip-copy)
			_copy='2'
			shift 1
		;;
		/*)
			a='1'
			while [ "${#}" -gt '0' ]; do
				_path="$(readlink -f "${_root_path}$(echo "${1}" | sed 's#^/rootfs##')" | sed 's#^/rootfs##')"
				echo "Will mount folder \"${_mount_to}${_path}\" in bindfs format to \"${_path}\""
				if [ ! -e "${_root_path}${_path}" ]; then
					echo "status: Failure"
					echo "Log: No such file or directory"
				else
					if mount | grep -q " on ${_path} (bindfs"; then
						case "${_copy}" in
							1)
								echo "status: Failure"
								echo "Log: Directory \"${_path}\" has been mounted"
								"${0}" -u "${_path}"
								"${0}" --copy "${_path}"
								;;
							*)
								echo "status: Failure"
								echo "Log: Directory \"${_path}\" has been mounted"
								_exit_status='1'
								;;
						esac
					else
						case "${_copy}" in
							0)
								if [ ! -d "${_mount_to}${_path}" ]; then
									mkdir -p "${_mount_to}${_path}"
									rm -rf "${_mount_to}${_path}"
									cp -a "${_root_path}${_path}" "${_mount_to}${_path}"
								elif [ "$(ls "${_mount_to}${_path}" | wc -l)" = '0' ]; then
									rm -rf "${_mount_to}${_path}"
									cp -a "${_root_path}${_path}" "${_mount_to}${_path}"
								else
									sleep 0
								fi
								;;
							1)
								mkdir -p "${_mount_to}${_path}"
								rm -rf "${_mount_to}${_path}"
								cp -a "${_root_path}${_path}" "${_mount_to}${_path}"
								;;
							2)
								mkdir -p "${_mount_to}${_path}"
								;;
						esac
						_do '-m' "${_mount_to}${_path}" "${_path}"
					fi
				fi
				if [ ! "${_exit_status}" = '0' ]; then
					_exit_status_a='1'
				fi
				unset _path _exit_status
				shift 1
			done
			if [ "${_exit_status_a}" = '1' ]; then
				exit 1
			else
				exit 0
			fi
		;;
		-u)
			shift 1
			a='1'
			while [ "${#}" -gt '0' ]; do
				case "${1}" in
					/*)
						_path="$(readlink -f "${_root_path}$(echo "${1}" | sed 's#^/rootfs##')" | sed 's#^/rootfs##')"
						echo "Will umount folder \"${_mount_to}${_path}\" on \"${_path}\""
						if mount | grep -q " on ${_path} (bindfs"; then
							_do '-u' "${_path}"
						else
							echo "status: Failure"
							echo "Log: Directory \"${_path}\" has not been mounted"
							_exit_status='1'
						fi
						;;
					*)
						echo 'Error: invalid path' 1>&2
						_exit_status='1'
						;;
				esac
				if [ ! "${_exit_status}" = '0' ]; then
					_exit_status_a='1'
				fi
				unset _path _exit_status
				shift 1
			done
			if [ "${_exit_status_a}" = '1' ]; then
				exit 1
			else
				exit 0
			fi
		;;
		-s)
			shift 1
			if [ -z "${1}" ]; then
				echo 'Will configured mount paths are about to be cleared'
				plutil -remove -key 'path' "${_p_file}" 1>>/dev/null
				echo "status: Success"
				exit 0
			fi
			if [ ! -f "${_p_file}" ]; then
				plutil -create "${_p_file}" 1>>/dev/null
				plutil -key 'Enable' -true "${_p_file}" 1>>/dev/null
				plutil -key 'root' -string '.jbroot/bindfs' "${_p_file}" 1>>/dev/null
			else
				plutil -remove -key path "${_p_file}" 1>>/dev/null
			fi
			plutil -key 'path' -array "${_p_file}" 1>>/dev/null
			echo 'The following paths will be mounted on the next userspace starts'
			echo ''
			a='1'
			while [ "${#}" -gt '0' ]; do
				_path="$(readlink -f "${_root_path}$(echo "${1}" | sed 's#^/rootfs##')" | sed 's#^/rootfs##')"
				if [ -e "${_root_path}${_path}" ]; then
					plutil -key 'path' -arrayadd -string "${_path}" "${_p_file}" 1>>/dev/null
					echo "${_path}"
				fi
				unset _path
				shift 1
				a="$((a+1))"
			done
			exit 0
		;;
		-l)
			if [ ! -f "${_p_file}" ]; then
				echo 'You have not set any folder for automatic mount.'
				exit 0
			fi
			i='0'
			while [ '1' -le '2' ]; do
				_path="$(plutil -key 'path' -key "${i}" "${_p_file}" 2>&1)"
				if echo "${_path}" | grep -q '^Error: Object not found at keypath'; then
					exit 0
				else
					echo "${_path}"
				fi
				i="$((i+1))"
			done
		;;
		*)
			echo 'Error: invalid path' 1>&2
			exit 2
		;;
	esac
done
