#!/bin/sh

# Files and Directories
GUEST_STORAGE_DEVICES_GUEST="/tmpHost/storage.guest"
HOST_STORAGE_DEVICES_GUEST="${MEDIACASTER_DIR}${GUEST_STORAGE_DEVICES_GUEST}"

GUEST_STORAGE_DEVICES_INFO_GUEST="/tmpHost/storageinfo.guest"
HOST_STORAGE_DEVICES_INFO_GUEST="${MEDIACASTER_DIR}${GUEST_STORAGE_DEVICES_INFO_GUEST}"

GUEST_STORAGE_DEVICES_HOST="/tmpHost/storage.host"
HOST_STORAGE_DEVICES_HOST="${MEDIACASTER_DIR}${GUEST_STORAGE_DEVICES_HOST}"

GUEST_STORAGE_DEVICES_INFO_HOST="/tmpHost/storageinfo.host"
HOST_STORAGE_DEVICES_INFO_HOST="${MEDIACASTER_DIR}${GUEST_STORAGE_DEVICES_INFO_HOST}"

GUEST_DAEMON_MEDIA_MAP_D="/etc/daemon.d/media-map.d"
HOST_DAEMON_MEDIA_MAP_D="${MEDIACASTER_DIR}${GUEST_DAEMON_MEDIA_MAP_D}"

GUEST_PATH_MAPPING="/tmpHost/path_mapping.txt"
HOST_PATH_MAPPING="${MEDIACASTER_DIR}${GUEST_PATH_MAPPING}"

GUEST_MOUNT_PREFIX="/home/0external/"
HOST_MOUNT_PREFIX="$MEDIACASTER_DIR${GUEST_MOUNT_PREFIX}"

GUEST_SDCARD_PREFIX="/home/0external/SDcard-internal/"
HOST_SDCARD_PREFIX="$MEDIACASTER_DIR$GUEST_SDCARD_PREFIX"

HOST_MOUNTS_CONF="$MEDIACASTER_DIR/etc/host-mounts.conf"

daemon_media_mount_start () {
	daemon_media_mount_static_start
	daemon_media_mount_dynamic_start
}

daemon_media_mount_stop () {
	daemon_media_mount_dynamic_stop
	daemon_media_mount_static_stop
}

daemon_media_mount_compare_state () {
	# Do a quick compare
	daemon_media_mount_scan_devices 0
	diff -q ${HOST_STORAGE_DEVICES_HOST} ${HOST_STORAGE_DEVICES_GUEST} > /dev/null
	return $?
}

# Parse the mount table into two FS_SPEC lists:
#  - removable media mounted by the host
#  - removable media mounted by the guest
daemon_media_mount_scan_devices () {
	local FS_SPEC
	local FS_FILE
	local IS_HOST
	local FULL=$1

	local DEVICES_OUTPUT
	local DEVICES_INFO_OUTPUT

	# Recreate temporary storage lists
	rm -f ${HOST_STORAGE_DEVICES_HOST}.tmp ${HOST_STORAGE_DEVICES_GUEST}.tmp
	touch ${HOST_STORAGE_DEVICES_HOST}.tmp ${HOST_STORAGE_DEVICES_GUEST}.tmp
	if [ "1" == "$FULL" ]; then
		rm -f ${HOST_STORAGE_DEVICES_INFO_HOST}.tmp ${HOST_STORAGE_DEVICES_INFO_GUEST}.tmp
		touch ${HOST_STORAGE_DEVICES_INFO_HOST}.tmp ${HOST_STORAGE_DEVICES_INFO_GUEST}.tmp
	fi

	HOST_MOUNTS=`cat ${HOST_MOUNTS_CONF}`

	while read LINE; do
		# Source is the first field in the mount table
		FS_SPEC=`echo "$LINE" | awk '{ print $1 }'`
		# Target is the second field in the mount table
		FS_FILE=`echo "$LINE" | awk '{ print $2 }'`

		# Determine which environment the mount belongs to
		if daemon_media_mount_classify "${FS_FILE}" "${HOST_MOUNT_PREFIX}"; then
			DEVICES_OUTPUT=${HOST_STORAGE_DEVICES_GUEST}.tmp
			DEVICES_INFO_OUTPUT=${HOST_STORAGE_DEVICES_INFO_GUEST}.tmp
			IS_HOST=0
		elif daemon_media_mount_classify "${FS_FILE}" "${HOST_MOUNTS}"; then
			DEVICES_OUTPUT=${HOST_STORAGE_DEVICES_HOST}.tmp
			DEVICES_INFO_OUTPUT=${HOST_STORAGE_DEVICES_INFO_HOST}.tmp
			IS_HOST=1
		else
			continue
		fi

		# Write the device name to the device file
		echo "$FS_SPEC" >> ${DEVICES_OUTPUT}

		if [ "1" == "$FULL" ]; then
			# Write the full device info to the device info file
			if [ "1" == "$IS_HOST" ]; then
				UUID=`blkid "${FS_SPEC}" | sed -n 's/.* UUID="\([^\"]*\)".*/\1/p'`
			else
				UUID=`basename "$FS_FILE"`
				FS_FILE=${FS_FILE#${MEDIACASTER_DIR}}
			fi
			echo "$FS_SPEC" "$UUID" "$FS_FILE" >> ${DEVICES_INFO_OUTPUT}
		fi
	done < /proc/mounts

	# TODO: Make moves atomic (rewrite media-mount in C, use single file)

	# Make the device lists unique
	cat ${HOST_STORAGE_DEVICES_HOST}.tmp | sort -u -o ${HOST_STORAGE_DEVICES_HOST}
	cat ${HOST_STORAGE_DEVICES_GUEST}.tmp | sort -u -o ${HOST_STORAGE_DEVICES_GUEST}

	# Make the device info lists unique
	if [ "1" == "$FULL" ]; then
		cat ${HOST_STORAGE_DEVICES_INFO_HOST}.tmp | sort -u -o ${HOST_STORAGE_DEVICES_INFO_HOST}
		cat ${HOST_STORAGE_DEVICES_INFO_GUEST}.tmp | sort -u -o ${HOST_STORAGE_DEVICES_INFO_GUEST}
	fi

}

daemon_media_mount_classify () {
	local MOUNTPOINT=$1
	local DIRS=$2
	local DIR

	for DIR in ${DIRS}; do
		if echo ${MOUNTPOINT} | grep "^${DIR}" > /dev/null; then
			return 0
		fi
	done
	return 1
}

daemon_media_mount_state_changed () {
	# Calculate uuid list for host media mounts
	daemon_media_mount_scan_devices 1

	# We will rewrite the guest's device info file so delete it now
	rm -f ${HOST_STORAGE_DEVICES_INFO_GUEST}

	# Iterate through each host media uuid and make sure we have a mounted guest media directory
	while read LINE ; do
		FS_SPEC=`echo ${LINE} | awk '{ print $1 }'`
		FS_UUID=`echo ${LINE} | awk '{ print $2 }'`
		FS_FILE=`echo ${LINE} | awk '{ print $3 }'`

		if [ ! -d "${HOST_MOUNT_PREFIX}${FS_UUID}" ]; then
			daemon_media_mount_mount "${FS_FILE}" "${FS_UUID}"
		fi

		echo "$FS_SPEC" "$FS_UUID" "${FS_FILE}" >> ${HOST_STORAGE_DEVICES_INFO_GUEST}
		echo "${FS_UUID}" >> ${HOST_STORAGE_DEVICES_GUEST}.found
	done < ${HOST_STORAGE_DEVICES_INFO_HOST}

	# Iterate through any guest media directories we didnt see and unmount them
	if [ "" != "`ls ${HOST_MOUNT_PREFIX}`" ]; then
		for SUBDIR in ${HOST_MOUNT_PREFIX}*; do
			UUID=`basename ${SUBDIR}`
			if ! grep -q  "^${UUID}" ${HOST_STORAGE_DEVICES_GUEST}.found ; then
				daemon_log_debug "Found stale guest mount: $SUBDIR"
				daemon_media_mount_unmount "${SUBDIR}"
			fi
		done
	fi

	# Delete the list of UUIDs we found mounted
	rm -f ${HOST_STORAGE_DEVICES_GUEST}.found

	# Regenerate the path_mapping.txt
	daemon_media_mount_map_paths
}

daemon_media_mount_mount () {
	HOSTDIR="$1"
	UUID="$2"
	SUBDIR="${HOST_MOUNT_PREFIX}${UUID}"

	daemon_log_info "Mounting ${SUBDIR}"

	mkdir -p "${SUBDIR}"

	if [ "0" == "$isBuildroot" ]; then
		sudo mount -o bind "${HOSTDIR}" "${SUBDIR}"
	else
		mount -o bind "${HOSTDIR}" "${SUBDIR}"
	fi

	return $?
}

daemon_media_mount_unmount () {
	SUBDIR="$1"

	daemon_log_info "Unmounting ${SUBDIR}"

	if [ "0" == "$isBuildroot" ]; then
		sudo umount "${SUBDIR}"
	else
		umount "${SUBDIR}"
	fi

	RETVAL=$?
	# TODO: sleep loop?
	rmdir "${SUBDIR}"
	return ${RETVAL}
}

daemon_media_mount_dynamic_start () {
	# Mount anything found as guest media mounts
	daemon_log_debug "Initializing media mounts."
	daemon_media_mount_state_changed
}

daemon_media_mount_dynamic_stop () {
	daemon_log_debug "Finalizing media mounts."
    if [ "`ls ${HOST_MOUNT_PREFIX}`" != "" ]; then
		for SUBDIR in ${HOST_MOUNT_PREFIX}*; do
			daemon_media_mount_unmount "$SUBDIR"
		done
	fi
}

# Mount the static mounts for the guest environment
daemon_media_mount_static_start () {
	if [ -d /sdcard/DCIM ] ; then

		for SUBDIR in "DCIM Movies Pictures Download Music Podcasts"; do
			mkdir -p "${HOST_SDCARD_PREFIX}/${SUBDIR}"
			mount "/sdcard/${SUBDIR}" "${HOST_SDCARD_PREFIX}/${SUBDIR}"
		done

		chmod 555 "$HOST_SDCARD_PREFIX"
	fi
}

daemon_media_mount_static_stop () {
	if [ ! -d ${HOST_SDCARD_PREFIX} ]; then
		return
	fi

	for SUBDIR in "DCIM Movies Pictures Download Music Podcasts"; do
		umount "${HOST_SDCARD_PREFIX}/${SUBDIR}"
	done
}

daemon_media_mount_map_paths () {
    if [ "`ls -A ${HOST_DAEMON_MEDIA_MAP_D}/* 2>/dev/null`" != "" ]; then
    	rm -f ${HOST_PATH_MAPPING}.tmp
    	touch ${HOST_STORAGE_DEVICES_INFO_GUEST}
        for each in ${HOST_DAEMON_MEDIA_MAP_D}/*; do
        	daemon_log_info "Executing media-map part: $each"
            sh ${each} \
            	"${HOST_STORAGE_DEVICES_INFO_GUEST}" \
            	"${GUEST_MOUNT_PREFIX}"
        done > ${HOST_PATH_MAPPING}.tmp
        mv ${HOST_PATH_MAPPING}.tmp ${HOST_PATH_MAPPING}
	else
		touch ${HOST_PATH_MAPPING}
    fi
}
