#!/bin/sh

# if run within buildroot create default configs and exit
if [ -n "${IPKG_INSTROOT}" ]; then
	echo "am1-s9" > ${IPKG_INSTROOT}/etc/bos_platform
	echo "src/gz bos_firmware https://feeds.braiins-os.com/am1-s9" > ${IPKG_INSTROOT}/etc/opkg/bosfeeds.conf
	cat > "${IPKG_INSTROOT}/etc/opkg/custombosfeeds.conf" <<-END
		# add your custom package feeds here
		#
		# src/gz bos_firmware_nightly https://feeds-nightly.braiins-os.com/am1-s9
	END
	exit 0
fi

# ensure compatibility with old firmwares which does not have bos_mode marker
# moreover, old firmware has package installed only in NAND mode
if [ -f "/lib/functions/bos-defaults.sh" ]; then
	. /lib/functions/bos-defaults.sh
fi

PACKAGES_NAME="Packages"
PACKAGES_PATH="/tmp/${PACKAGES_NAME}"
SYSUPGRADE_PATH="/tmp/sysupgrade.tar"
BOS_FEEDS="/etc/opkg/bosfeeds.conf"
BOS_FEEDS_RECORD="bos_firmware"
FIRMWARE_NAME="firmware_2022-09-27-0-26ba61b9-22.08.1-plus_arm_cortex-a9_neon.tar"
FIRMWARE_REQUIRE="2022-09-13-0-11012d53-22.08-plus"

if [ ! -f "${BOS_FEEDS}" ]; then
	# fallback for old miner firmwares
	BOS_FEEDS="/etc/opkg/minerfeeds.conf"
	BOS_FEEDS_RECORD="miner_firmware"
fi
if [ ! -f "${BOS_FEEDS}" ]; then
	echo "Missing configuration file /etc/opkg/bosfeeds.conf!" >&2
	exit 1
fi

# parse server address from opkg configuration file
feeds_server=$(awk '/^[^#]/ && $2 ~ /^'${BOS_FEEDS_RECORD}'$/ {print $3}' /etc/opkg/*.conf | tail -n1)

if [ -z "${feeds_server}" ]; then
	echo "Cannot find feeds server in '/etc/opkg/' configuration files!" >&2
	echo "Configuration with '${BOS_FEEDS_RECORD}' is probably missing." >&2
	exit 1
fi

current_fw_version() {
	if ! cat /etc/bos_version 2>/dev/null; then
		awk '/Package: /{p=$2} /Version: /{v=$2} /Status: /{if (p == "firmware" && $NF == "installed") print v}' '/usr/lib/opkg/status'
	fi
}

required_fw_version() {
	result=$(awk '/Package: /{p=$2} /Version: /{v=$2} /Require: /{r=$2} /Filename: /{if (p == "firmware" && v == "'$2'") print $2" "r}' "$1")
	eval $3=${result% *}
	eval $4=${result#* }
}

get_firmware_name() {
	local fw_version=$(current_fw_version)
	local require=${FIRMWARE_REQUIRE}
	local filename=${FIRMWARE_NAME}
	local filename_prefix=
	[ "$BOS_MODE" == 'sd' ] && filename_prefix="sd-"

	if [ ! "${fw_version}" "<" "${require}" ]; then
		eval $1="${filename_prefix}${filename}"
		return 0
	fi

	echo "Downloading package list..."
	wget -O "${PACKAGES_PATH}.gz" "${feeds_server}/${PACKAGES_NAME}.gz" || return 1
	gzip -df "${PACKAGES_PATH}.gz" || return 1
	wget -O "${PACKAGES_PATH}.sig" "${feeds_server}/${PACKAGES_NAME}.sig" || return 1
	echo "Checking signature..."
	usign -V -m "${PACKAGES_PATH}" -P "/etc/opkg/keys" || return 1

	while [ "${fw_version}" "<" "${require}" ]; do
		required_fw_version "${PACKAGES_PATH}" ${require} filename require
		[ -n "${filename}" ] || return 1
	done
	echo "Using previous firmware to satisfy requirements!"
	eval $1="${filename_prefix}${filename%.ipk}.tar"
}

if get_firmware_name firmware_name; then
	echo "Running system upgrade..."
	wget -O "${SYSUPGRADE_PATH}" "${feeds_server}/${firmware_name}" || exit 1
	sysupgrade "${SYSUPGRADE_PATH}"
else
	echo "Firmware version '${FIRMWARE_REQUIRE}' is required before upgrading to this version." >&2
	echo "Cannot find required firmware on server!" >&2
	exit 1
fi

# the package is not actually installed
# wait to suppress error printing
sleep 10
exit 2
