#!/bin/sh

# this script assumes anything on the disk can be removed if corrupted
# other use cases may need different scripts.

# currently only supports ext4 but should be expanded

proc do_fsck {
	# preen
	/sbin/e2fsck -p $[join(ARGV)]
	setvar EXIT_CODE = ""$?
	# exit code 1 is errors corrected
	test ${EXIT_CODE} -eq 1 && setvar EXIT_CODE = '0'
	# exit code 2 or 3 means need to reboot
	test ${EXIT_CODE} -eq 2 -o ${EXIT_CODE} -eq 3 && /sbin/reboot
	# exit code 4 or over is fatal
	test ${EXIT_CODE} -lt 4 && return "${EXIT_CODE}"

	# try harder
	/sbin/e2fsck -y $[join(ARGV)]
	# exit code 1 is errors corrected
	test ${EXIT_CODE} -eq 1 && setvar EXIT_CODE = '0'
	# exit code 2 or 3 means need to reboot
	test ${EXIT_CODE} -eq 2 -o ${EXIT_CODE} -eq 3 && /sbin/reboot
	# exit code 4 or over is fatal
	test ${EXIT_CODE} -ge 4 && printf "Filesystem unrecoverably corrupted, will reformat\n"

	return "${EXIT_CODE}"
}

proc do_fsck_extend_mount {
	setvar DRIVE = "$1"
	setvar DATA = "$2"

	do_fsck $DATA || return 1

	# only try to extend if there is a single partition and free space
	setvar PARTITIONS = $(sfdisk -J "$DRIVE" | jq '.partitiontable.partitions | length')

	if test $PARTITIONS -eq 1 && \
		sfdisk -F $DRIVE | grep -q 'Unpartitioned space' &&
		! sfdisk -F $DRIVE | grep -q '0 B, 0 bytes, 0 sectors'
	{
		setvar SPACE = $(sfdisk -F "$DRIVE" | grep 'Unpartitioned space')
		printf "Resizing disk partition: $SPACE\n"

		# 83 is Linux partition id
		setvar START = $(sfdisk -J "$DRIVE" | jq -e '.partitiontable.partitions | map(select(.type=="83")) | .[0].start')

		sfdisk -q --delete $DRIVE 2> /dev/null
		echo "${START},,83;" | sfdisk -q $DRIVE

		# set bootable flag
		sfdisk -A $DRIVE 1

		# update status
		blockdev --rereadpt $diskdev 2> /dev/null
		mdev -s

		# wait for device
		for i in $(seq 1 50) { test -b $DATA && break || sleep .1; mdev -s; }

		# resize2fs fails unless we use -f here
		do_fsck -f $DATA || return 1
		resize2fs $DATA

		do_fsck $DATA || return 1
	}
}

proc do_mkfs {
	setvar diskdev = "$1"

	# new disks does not have an DOS signature in sector 0
	# this makes sfdisk complain. We can workaround this by letting
	# fdisk create that DOS signature, by just do a "w", a write.
	# http://bugs.alpinelinux.org/issues/145
	echo "w" | fdisk $diskdev >/dev/null

	# format one large partition
	echo ";" | sfdisk --quiet $diskdev

	# update status
	blockdev --rereadpt $diskdev 2> /dev/null

	# wait for device
	for i in $(seq 1 50) { test -b $DATA && break || sleep .1; mdev -s; }

	setvar FSOPTS = ""-O resize_inode,has_journal,extent,huge_file,flex_bg,uninit_bg,64bit,dir_nlink,extra_isize""

	mkfs.ext4 -q -F $FSOPTS ${diskdev}1
}

# TODO fix for multiple disks, cdroms etc
setvar DEV = "$(find /dev -maxdepth 1 -type b ! -name 'loop*' | grep -v '[0-9]$' | sed 's@.*/dev/@@' | sort | head -1 )"

test -z ${DEV} && exit 1

setvar DRIVE = ""/dev/${DEV}""

# see if it has a partition table already
if sfdisk -d ${DRIVE} >/dev/null 2>/dev/null
{
	setvar DATA = $(sfdisk -J "$DRIVE" | jq -e -r '.partitiontable.partitions | map(select(.type=="83")) | .[0].node')
	if test $? -eq 0
	{
		do_fsck_extend_mount $DRIVE $DATA || do_mkfs $DRIVE
	} else {
		do_mkfs $DRIVE
	}
} else {
	do_mkfs $DRIVE
}