# #alpine-config UserData Functions
# vim:set filetype=sh:
# shellcheck shell=sh

# NOTE: alpine-config extends cloud-config

: "${PREFIX:=/usr}"
: "${LIBDIR:=$PREFIX/lib}"
. "${LIBDIR}/tiny-cloud/user-data/cloud-config"

INIT_ACTIONS_MAIN="$(insert_after userdata_ntp "userdata_apk_cache userdata_apk_repositories" $INIT_ACTIONS_MAIN)"
INIT_ACTIONS_FINAL="$INIT_ACTIONS_FINAL userdata_autoinstall"

init__userdata_apk_cache() {
	local cache="$(get_userdata apk/cache)"
	if [ -z "$cache" ]; then
		return
	fi
	mkdir -p "$ROOT/$cache"
	# make link relative
	case "$cache" in
		/*) cache="../..$cache";;
	esac
	mkdir -p "$ETC"/apk
	ln -sf "$cache" "$ETC"/apk/cache
}

init__userdata_apk_repositories() {
	local apk="$(get_userdata apk)"
	if [ -z "$apk" ] && ! [ -e "$ETC"/apk/repositories ]; then
		$MOCK setup-apkrepos -1 -c
		return
	fi
	local repositories="$(get_userdata apk/repositories)"
	mkdir -p "$ETC"/apk
	for r in $repositories; do
		local baseurl="$(get_userdata apk/repositories/$r/base_url)"
		local repos="$(get_userdata apk/repositories/$r/repos)"
		local version="$(get_userdata apk/repositories/$r/version)"
		if [ -z "$version" ]; then
			local version_id=$( . "$ETC"/os-release 2>/dev/null && echo "$VERSION_ID")
			case "$version_id" in
				edge*|*_alpha*) version="edge";;
				[0-9]*.[0-9]*.[0-9]*) version="v${version_id%.*}";;
			esac
		fi
		if [ -n "$version" ] && [ "$version" != "." ] && [ "$version" != "/" ]; then
			baseurl="${baseurl%/}/$version"
		fi
		for repo in $repos; do
			local uri="${baseurl%/}/$(get_userdata apk/repositories/$r/repos/$repo)"
			add_once "$ETC"/apk/repositories "$uri"
		done
	done
}

find_biggest_empty_disk() {
	local d p
	for d in  "$SYS"/class/block/*/device; do
		p=${d%/device}
		if [ -e "$p"/size ] && [ -z "$(blkid /dev/${p##*/})" ]; then
			echo "$(cat $p/size) ${p##*/}"
		fi
	done | sort -n | tail -n 1 | cut -d' ' -f2
}

is_number() {
	case "$1" in
	    ''|*[!0-9]*) return 1 ;;
	esac
	return 0
}

init__userdata_autoinstall() {
	local autoinstall="$(get_userdata autoinstall)"
	local disk reboot swapsize uselvm
	if [ "$autoinstall" = "true" ]; then
		disk=auto
		reboot=true
	else
		disk="$(get_userdata autoinstall/disk)"
		if [ -z "$disk" ]; then
			log err "no disk specified"
			return
		fi
		reboot="$(get_userdata autoinstall/reboot)"
		: ${reboot:=true}

		swapsize="$(get_userdata autoinstall/swapsize)"
		uselvm="$(get_userdata autoinstall/lvm)"
		if [ "$uselvm" != "true" ]; then
			unset uselvm
		fi
	fi

	if [ "$disk" = "auto" ]; then
		disk="$(find_biggest_empty_disk)"
		if [ -z "$disk" ]; then
			log err "no empty disk found"
			return
		fi
		disk="/dev/$disk"
	fi

	if ! [ -b "$disk" ] && [ -z "$MOCK" ]; then
		log err "$disk is not a block device"
		return
	fi

	if [ -n "$swapsize" ] && ! is_number ${swapsize%[MG]}; then
		log err "swapsize is not valid: $swapsize"
		return
	fi

	case "$swapsize" in
		*M) swapsize=${swapsize%M};;
		*G) swapsize=$(( ${swapsize%G} * 1000));;
	esac

	rm -f "$ETC"/runlevels/*/tiny-cloud*
	$MOCK lbu include /root/.ssh /home
	ERASE_DISKS=/dev/$disk $MOCK setup-disk -m sys ${uselvm+-L} ${swapsize+-s ${swapsize}} $disk

	if [ "$reboot" = "true" ]; then
		$MOCK reboot
	fi
}
