#!/bin/bash

EXCLUDE=("/dev/*" "/proc/*" "/sys/*" "/media/*" "/mnt/*" "/run/*" "/tmp/*")
ROOT_DIR=$(dirname $(realpath "$0"))

source ${ROOT_DIR}/library.sh

function required_blocks
{
    _exclude=""
    for e in "${EXCLUDE[@]}"; do
        _exclude=${_exclude}" --exclude=${e}"
    done

    du -s --block-size=512 ${_exclude} / | awk '{print $1}'
}

echo -e "\nDetecting board..."
for comp in $(cat "/proc/device-tree/compatible" | tr '\0' '\n'); do
	if [[ "$comp" == "allwinner,sun"* ]]; then
		_soc=$(cut -d',' -f2 <<< $comp)
		break
	fi
	if [[ "$comp" == "st,stm32mp1"* ]]; then
		_soc=$(cut -d',' -f2 <<< $comp)
		break
	fi
done

if [[ -z ${_soc} ]]; then
    echo "Failed to detect the board type!" >&2
    exit 1
fi

case ${_soc} in
    "sun5i-a13")
        _board="a13-olinuxino"
        ;;
    "sun4i-a10")
        _board="a10-olinuxino"
        ;;
    "sun7i-a20")
        _board="a20-olinuxino"
        ;;
    "sun50i-a64")
        _board="a64-olinuxino"
        ;;
    "stm32mp1"*)
        _board="stm32mp1xx-olinuxino"
        ;;
    *)
        echo "Unsupported board family: ${_soc}!" >&2
        exit 1
        ;;
esac

echo -e "\nDetecting the root device..."
_root_partition=$(get_root_partition)
if [[ -z ${_root_partition} ]]; then
    echo "Failed to detect root partition!" >&2
    exit 1
fi

_root_device=$(get_root_device)
if [[ -z ${_root_device} ]]; then
    echo "Failed to detect root device!" >&2
    exit 1
fi
echo -e "Root partition:\t\t${_root_partition}"
echo -e "Root device:\t\t${_root_device}"

echo -e "\nDetecting eMMC device..."
_emmc_device=$(get_emmc_device)
_emmc_partition=$(sed "s/${_root_device#/dev/}/${_emmc_device#/dev/}/g" <<< ${_root_partition})

if [[ -z ${_emmc_device} ]]; then
    echo "Failed to detect eMMC device!" >&2
    exit 1
fi
echo -e "eMMC partition:\t\t${_emmc_partition}"
echo -e "eMMC device:\t\t${_emmc_device}"

echo -e "\nChecking disk size..."
_required=$(required_blocks)
_available=$(get_device_block_count ${_emmc_device})

echo -e "Required blocks:\t${_required}"
echo -e "Available blocks:\t${_available}"

if [[ ${_available} -lt ${_required} ]]; then
    echo "Not enough blocks to transfer the file-system!" >&2
    exit 1
fi

echo -e "\nUnmount target device..."
umount ${_emmc_partition} || true
sync

echo -e "\nCopying MBR record..."
dd if=/dev/zero of=${_emmc_device} bs=1M count=1 conv=sync,fsync 2>/dev/null
sync

if [ "${_board}" == "stm32mp1xx-olinuxino" ] ; then
    sgdisk -o ${_emmc_device}
    sgdisk --resize-table=128 -a 1 \
           -n 1:2048:6143 -c 1:ssbl \
           -n 4:6144: -c 4:rootfs \
           -p ${_emmc_device}
else
    # TODO fix
    sfdisk -q -d ${_root_device} | sed 's/size=.*,//g' | sfdisk -q --wipe=always ${_emmc_device}
fi

echo -e "\nResizing partition..."
resize_partition ${_emmc_partition}
e2fsck -f -y ${_emmc_partition}
resize2fs ${_emmc_partition}

echo -e "\nFormating disk..."
_type=$(get_partition_type ${_root_partition})
mkfs.${_type} -F ${_emmc_partition} > /dev/null 2>&1

echo -e "\nCopying disk..."
_mount=$(mktemp -d)
mount ${_emmc_partition} ${_mount}

_exclude=""
    for e in "${EXCLUDE[@]}"; do
        _exclude=${_exclude}" --exclude=${e}"
    done

rsync -a --info=progress2 --delete ${_exclude} / ${_mount}

echo -e "\nConfiguring..."
_root_uuid=$(get_partition_uuid ${_root_partition})
_emmc_uuid=$(get_partition_uuid ${_emmc_partition})
sed -i "s/${_root_uuid}/${_emmc_uuid}/g" ${_mount}/etc/fstab

echo -e "\nCleanup..."
umount ${_emmc_partition} || true
sync
rm -rf ${_mount}

echo -e "\nWriting bootloader..."
u-boot-install ${_emmc_device}

# If the target device is A20-OLinuXino and there is MTD device, connected on spi0 bus
# we presume that this is a board with both eMMC and SPI.
# On some boards there is booting issue from eMMC, so a backup copy of the U-Boot must be written
# to the SPI flash.
if [ "${_board}" == "a20-olinuxino" -o "${_board}" == "a10-olinuxino" ]; then
    _mtd_device=""
    while read line; do
        grep -q "spi0.0" <<< ${line} && \
            _mtd_device="/dev/$(cut -d':' -f1 <<< ${line})" && \
            break
    done <<< "$(cat /proc/mtd)"
    [[ ! -z ${_mtd_device} ]] && u-boot-install ${_mtd_device}
fi

