#!/bin/sh

SYSCFG_UBIFS_MNT=/tmp/syscfg
SLOT="$(find_system_slot)"
echo "Active system$SLOT"

get_current_rootfs_label() {
	rootfs_label="rootfs"
	echo "$rootfs_label"
}

mount_no_ubifs_syscfg_mtd() {
	mtd unlock $(get_current_rootfs_label)
	mount -o remount,rw /dev/root /
}

# return 1 on failed 0 for success
ubifs_volume_support() {
	mtdpart_idx="$(find_mtd_index rootfs_data)"
	[ -z "$mtdpart_idx" ] && return 1
	mtdpart_idx_oem="$(find_mtd_index oem_data$SLOT)"
	if [ -z "$mtdpart_idx_oem" ]
	then
		# oem_data may has only one partition
		mtdpart_idx_oem="$(find_mtd_index oem_data)"
		[ -z "$mtdpart_idx_oem" ] && return 1
	fi
	grep -qs ubifs /proc/filesystems ||  return 1
	echo "found rootfs_data partition and ubifs support"
	return 0
}

__try_ubifs_syscfg_mount() {
	overlay_mountpoint=$1
	if [ -z $overlay_mountpoint ]
	then
		overlay_mountpoint=/overlay
	fi
	recover_ubifs=0
	[ ! -e /dev/ubi0 ] && ubiattach /dev/ubi_ctrl -m $mtdpart_idx -d 0 || recover_ubifs=1
	if [ $recover_ubifs -eq 0 ]
	then
		ubi0_nod_id=`cat /sys/class/ubi/ubi0/dev | tr -s ":" " "`
		[ ! -e /dev/ubi0 ] && mknod /dev/ubi0 c ${ubi0_nod_id}
		if [ ! -e /sys/class/ubi/ubi0_0/dev ]
		then
			# no volume
			recover_ubifs=1
		else
			# check for "data" volume
			ubi0_0_nod_id=`cat /sys/class/ubi/ubi0_0/dev | tr -s ":" " "`
			[ ! -e /dev/ubi0_0 ] && mknod /dev/ubi0_0 c ${ubi0_0_nod_id}
			{ ubinfo /dev/ubi0_0 | grep Name  | grep -qs "data" ; } || \
			recover_ubifs=1
		fi
	fi
	if [ $recover_ubifs -eq 1 ]
	then
		echo "ubifs syscfg partition is damaged"
		echo "try to recover by formatting $mtdpart..."
		[ -e /dev/ubi0 ] && ubidetach -m $mtdpart_idx
		ubiformat -y -q /dev/mtd$mtdpart_idx
		ubiattach -m $mtdpart_idx /dev/ubi_ctrl
		ubi0_nod_id=`cat /sys/class/ubi/ubi0/dev | tr -s ":" " "`
		[ ! -e /dev/ubi0 ] && mknod /dev/ubi0 c ${ubi0_nod_id}
		ubimkvol /dev/ubi0 -n 1 -N etc -t dynamic -s 2MiB
		ubimkvol /dev/ubi0 -n 0 -N data -t dynamic --maxavsize
	fi

	# finally mount the ubifs
	mount -t ubifs -o noatime ubi0:data /data || return 1
	mount -t ubifs -o noatime ubi0:data /mnt || return 1
	mount -t ubifs -o noatime ubi0:data /log || return 1
	mount -t ubifs -o noatime ubi0:etc $overlay_mountpoint/etc || return 1
	return 0
}

try_ubifs_syscfg_mount() {
	__try_ubifs_syscfg_mount || {
		echo "roofs_data mount fail, try to recover by erase..."
		umount $overlay_mountpoint/etc
		umount /log
		umount /mnt
		umount /data
		mtd erase rootfs_data
		__try_ubifs_syscfg_mount
	}

	return 0
}

ubifs_oem_data_mount() {
	recover_ubifs=0
	[ ! -e /dev/ubi1 ] && ubiattach /dev/ubi_ctrl -m $mtdpart_idx_oem -d 1 || recover_ubifs=1
	if [ $recover_ubifs -eq 0 ]
	then
		ubi1_nod_id=`cat /sys/class/ubi/ubi1/dev | tr -s ":" " "`
		[ ! -e /dev/ubi1 ] && mknod /dev/ubi1 c ${ubi1_nod_id}
		if [ ! -e /sys/class/ubi/ubi1_0/dev ]
		then
			# no volume
			recover_ubifs=1
		else
			# check for "oem_data" volume
			ubi1_0_nod_id=`cat /sys/class/ubi/ubi1_0/dev | tr -s ":" " "`
			[ ! -e /dev/ubi1_0 ] && mknod /dev/ubi1_0 c ${ubi1_0_nod_id}
			{ ubinfo /dev/ubi1_0 | grep Name  | grep -qs "oem_data" ; } || \
			recover_ubifs=1
		fi
	fi
	if [ $recover_ubifs -eq 1 ]
	then
		echo "ubifs oem_data partition is damaged"
		echo "try to recover by formatting $mtdpart..."
		[ -e /dev/ubi1 ] && ubidetach -m $mtdpart_idx_oem
		ubiformat -y -q /dev/mtd$mtdpart_idx_oem
		ubiattach -m $mtdpart_idx_oem /dev/ubi_ctrl
		ubi1_nod_id=`cat /sys/class/ubi/ubi1/dev | tr -s ":" " "`
		[ ! -e /dev/ubi1 ] && mknod /dev/ubi1 c ${ubi1_nod_id}
		ubimkvol /dev/ubi1 -n 0 -N oem_data -t dynamic --maxavsize
	fi

	mkdir -p /NVM/oem_data
	mount -t ubifs -o ro,noatime,bulk_read ubi1:oem_data /NVM/oem_data
	return 0
}

create_overlay() { # <lowerdir> <upper_dir> <target>
	mkdir -p $2/root $2/work
	/bin/mount -o noatime,lowerdir=$1,upperdir=$2/root,workdir=$2/work -t overlay "overlayfs:$2" $3
}

ubifs_syscfg_rootfs_pivot() {
	echo "switching to ubifs sysfs overlay"

	mount -o bind / /rom

	# Dir /etc and /NVM can be written after creating overlay
	create_overlay /system/etc $overlay_mountpoint/etc /system/etc
#	create_overlay /NVM $overlay_mountpoint/nvm /NVM
	ubifs_oem_data_mount
}

do_mount_ubifs_overlay() {
	{ ubifs_volume_support && \
	try_ubifs_syscfg_mount && \
	ubifs_syscfg_rootfs_pivot ; } || mount_no_ubifs_syscfg_mtd
}

boot_hook_add preinit_main do_mount_ubifs_overlay
