#!/bin/bash -

# Copyright (C) MOXA Inc. All rights reserved.
# This software is distributed under the terms of the MOXA SOFTWARE NOTICE.
# See the file MOXA-SOFTWARE-NOTICE for details.
#
# Name:
#	MOXA Image Auto Install Configuration Utility
#
# Description:
#	Configure and Check Auto Install Information
#
# Copyright (C) Moxa, Inc. All rights reserved.
# Copyright (C) 2021	Remus Wu	<remusty.wu@moxa.com>
# Copyright (C) 2022	Henry LC Chen	<HenryLC.Chen@moxa.com>

BASENAME="mx-image-auto-install-tool"
INTERFACE_NAME="mx-bootloader-mgmt image_auto_install"
AUTO_INSTALL_CMD=rfi_cmd

_logger() {
	echo "$1"
	logger -i -t $BASENAME "$1"
}

configuration_is_set() {
	local info
	info=$(fw_printenv -n $AUTO_INSTALL_CMD 2>&1)

	if grep -q "## Error:" <<< "$info"; then
		_logger "Error: configuration is not set"
		return 1
	elif [ "$info" == "" ]; then
		_logger "Error: configuration is not set"
		return 1
	fi

	return 0
}

info() {
	local info
	info=$(fw_printenv -n $AUTO_INSTALL_CMD 2>&1)

	_logger "Image auto install configuration:"
	_logger "Image File: $(echo "$info" | cut -d ',' -f 3)"
	_logger "Disk Name: $(echo "$info" | awk -F ',' '{ print toupper($1) }')"
}

configure() {
	local secure
	local dir
	local fstype
	local image
	secure=$(fw_printenv -n secure 2>&1)
	dir=$(mount | grep "$(mx-interface-mgmt disk "$DISK" | grep PARTITION_1 | cut -d= -f2)" | awk '{ print $3 }')
	fstype=$(mount | grep "$dir" | awk '{ print $5 }')
	image=$dir/$(basename "$FILE")
	local suffix=sha256sum.bin

	if [ "$(uname -m)" = "aarch64" ]; then
		suffix=sha512sum.bin
	fi
	if [ "$secure" = 1 ]; then
		suffix=${suffix}.signed
	fi

	if [ "$fstype" != "vfat" ] && [ "$fstype" != "ext4" ]; then
		_logger "Error: filesystem type $fstype is not support, required 'FAT' or 'EXT4'"
		return 1
	elif ! find "$dir" -type f -name "$(basename "$FILE")" > /dev/null; then
		_logger "Error: $FILE is not exist."
		return 1
	elif [ ! -f "$image" ]; then
		_logger "Error: $(basename "$image") is not in the root directory of $DISK"
		return 1
	elif [ ! -f "${image}".${suffix} ]; then
		_logger "Error: ${FILE}.${suffix} is not exist"
		return 1
	fi

	# fw_setenv rfi_cmd 'usb,1,FWR_UC-3100_develop.img'
	# fw_setenv rfi_cmd 'sd,1,FWR_UC-3100_develop.img'
	fw_setenv $AUTO_INSTALL_CMD "${DISK,,},1,$(basename "$image")"
	info
}

usage() {
	echo "Usage: $INTERFACE_NAME [OPTION] [-f <FILE>]"
	echo
	echo "Examples:"
	echo "  $INTERFACE_NAME -d SD -f IMG_UC-8200_MIL3_V1.0_Build_22042223.img  # Install Image from SD Card"
	echo "  $INTERFACE_NAME -d USB -f IMG_UC-8200_MIL3_V1.0_Build_22042223.img # Install Image from USB DISK"
	echo
	echo "Options:"
	echo "  -d, --disk <disk>      Set <disk> as disk name of image location, based on 'NAME' from 'mx-interface-mgmt disk'"
	echo "  -f, --file <file>      Set <file> as image file"
	echo "  -i, --info             Get the configured parameters of auto installation"
	echo "  -r, --remove           Disable auto installation upon next boot"
	echo
	echo "  -h, --help             Display the help menu"
}

parsing_options() {
	if ! OPTS=$(getopt -o d:f:irh --long disk:,file:,info,remove,help -n "$INTERFACE_NAME" -- "$@"); then
		echo "Failed parsing options." >&2
		exit 1
	fi
	eval set -- "$OPTS"

	while [ -n "$1" ]; do
		case "$1" in
		-d | --disk)
			if [ -n "$DISK" ]; then
				return 1
			fi
			DISK="$2"
			shift 2
			;;
		-i | --info)
			if [ -n "$ACTION" ]; then
				return 1
			fi
			ACTION=info
			shift
			;;
		-f | --file)
			if [ -n "$FILE" ]; then
				return 1
			fi
			FILE="$2"
			shift 2
			;;
		-r | --remove)
			if [ -n "$ACTION" ]; then
				return 1
			fi
			ACTION=remove
			shift
			;;
		-h | --help)
			usage
			exit 0
			;;
		--)
			shift
			break
			;;
		*)
			shift
			break
			;;
		esac
	done

	if [ -z "$ACTION" ]; then
		if [ -z "$FILE" ]; then
			echo "Error: image name is not set"
			return 1
		elif [ -z "$DISK" ]; then
			echo "Error: disk name is not set"
			return 1
		elif ! mx-interface-mgmt disk "$DISK" > /dev/null; then
			echo "Error: incorrect disk name '$DISK'"
			return 1
		elif [ "$(mx-interface-mgmt disk "$DISK" | grep NUMBER_OF_PARTITIONS | cut -d= -f2)" != 1 ]; then
			echo "Error: '$DISK' has more than one partition"
			return 1
		elif ! mount | grep -q "$(mx-interface-mgmt disk "$DISK" | grep PARTITION_1 | cut -d= -f2)"; then
			echo "Error: disk '$DISK' is not mount"
			return 1
		fi
		ACTION=configure
	fi

	return 0
}

main() {
	if ! parsing_options "$@"; then
		usage
		return 1
	fi

	case "$ACTION" in
	configure)
		if ! configuration_is_set > /dev/null; then
			configure || return 1
		else
			_logger "Warning: configuration has been set"
			info
			return 1
		fi
		;;
	info)
		if configuration_is_set; then
			info
		else
			_logger "Warning: configuration is not set"
			return 1
		fi
		;;
	remove)
		if configuration_is_set; then
			fw_setenv $AUTO_INSTALL_CMD
			if ! configuration_is_set > /dev/null; then
				_logger "Configuration is clear."
			else
				_logger "Error: configuration clear failed."
				return 1
			fi
		fi
		;;
	*)
		;;
	esac

	return 0
}

main "$@"
exit "$?"
