#!/bin/sh -ex

# Return codes used in this script:
# 1: Current system is already mounted.
# 2: Offline system is already mounted.
# 3: fsck.ext2 returned code not equal to 0 (zero).

# Initialize Device Stack return variable.
# This shall be done as early as possible.
CLONE_STATUS_FILE=/opt/userdata/.clone-status
printf "started" > ${CLONE_STATUS_FILE}

MMC_SYSTEM_A=$(cat /opt/extparam/system_A_root_blkdev)
MMC_SYSTEM_B=$(cat /opt/extparam/system_B_root_blkdev)

CURRENT_SYSTEM_DIR="/opt/userdata/fwu/system_current"
OFFLINE_SYSTEM_DIR="/opt/userdata/fwu/system_offline"

MMC_SYSTEM_OFFLINE=$(cat /opt/extparam/offline_root_blkdev)
MMC_SYSTEM_CURRENT=$(cat /opt/extparam/booted_root_blkdev)

FILESYSTEM_TYPE=ext3

finish()
{
  printf "executing cleanup trap\\n"
  trap - INT TERM EXIT
  if [ $(mount | grep "${CURRENT_SYSTEM_DIR}" | wc -l) -gt 0 ]
  then
    umount ${CURRENT_SYSTEM_DIR}
  fi
  if [ $(mount | grep "${OFFLINE_SYSTEM_DIR}" | wc -l) -gt 0 ]
  then
    umount ${OFFLINE_SYSTEM_DIR}
  fi
}

trap finish INT TERM EXIT

printf "MMC_SYSTEM_A:%s\\n" "${MMC_SYSTEM_A}"
printf "MMC_SYSTEM_B:%s\\n" "${MMC_SYSTEM_B}"
printf "MMC_SYSTEM_CURRENT:%s\\n" "${MMC_SYSTEM_CURRENT}"
printf "MMC_SYSTEM_OFFLINE:%s\\n" "${MMC_SYSTEM_OFFLINE}"

# Ensure, that both mount points are unmounted.
# Unmount is done by trap and will not retried here.
[ $(mount | grep "${CURRENT_SYSTEM_DIR}" | wc -l) -gt 0 ] && printf "Current system is already mounted. Stopping.\\n" && exit 1
[ $(mount | grep "${OFFLINE_SYSTEM_DIR}" | wc -l) -gt 0 ] && printf "Offline system is already mounted. Stopping.\\n" && exit 2

CLONE_METHOD="cp"
#CLONE_METHOD="dd"
#CLONE_METHOD="none"

case "${CLONE_METHOD}" in
	cp)
		printf "Cloning via copy method.\\n"

		# Mount current system read-only.
		mkdir -p ${CURRENT_SYSTEM_DIR}
		mount -t ${FILESYSTEM_TYPE} -o ro ${MMC_SYSTEM_CURRENT} ${CURRENT_SYSTEM_DIR}

		# Erase the offline system.
		mkfs.${FILESYSTEM_TYPE} -F ${MMC_SYSTEM_OFFLINE}

		# Mount offline system writable.
		mkdir -p ${OFFLINE_SYSTEM_DIR}
		mount -t ${FILESYSTEM_TYPE} -o noatime,nodiratime ${MMC_SYSTEM_OFFLINE} ${OFFLINE_SYSTEM_DIR}

		# Copy the current system files to offline
		(cd ${CURRENT_SYSTEM_DIR} && cp -a . ${OFFLINE_SYSTEM_DIR})
		sync
		;;
	dd)
		printf "Cloning via dd method.\\n"

		# 4M is the preferred erase size of typical SD Cards.
		# As this is an eMMC we have a preferred erase size of 512k.
		dd if=${MMC_SYSTEM_CURRENT} of=${MMC_SYSTEM_OFFLINE} bs=512k
		sync
		;;
	*)
		printf "No clone method selected.\\n"
		;;
esac

umount ${CURRENT_SYSTEM_DIR} || printf "Failed to unmount current system (%s).\\n" "${CURRENT_SYSTEM_DIR}"
umount ${OFFLINE_SYSTEM_DIR} || printf "Failed to unmount offline system (%s).\\n" "${OFFLINE_SYSTEM_DIR}"

fsck.${FILESYSTEM_TYPE} -y ${MMC_SYSTEM_OFFLINE}
EXIT_CODE=$?
if ! [ ${EXIT_CODE} -eq 0 ]
then
  printf "Filesystemcheck returned non-zero (code: |%s|). Stopping.\\n" "${EXIT_CODE}"
  exit 3
fi

printf "stopped" > ${CLONE_STATUS_FILE}
printf "The clone script has successfully done it's job and will now exit with return code 0.\\n"

exit 0
