#!/bin/sh
. /usr/local/bin/sig_catcher
UPDATE_BOOT=0
UPDATE_FIRMWARE=0

compare_revision() {
	local ret_val=0
	if [ $1 -eq 0 ]; then
		local file_name=$new_firmware_name
	else
		local file_name=$new_boot_name
	fi
	local dev_rev=$(echo $installed_version | sed -e 's/F[CB]//g' | cut -d " " -f 2)
	local file_rev=$(echo $file_name | awk -F_ '{printf $NF}' | sed -e 's/.[a-z]//g')
	if [ "$file_rev" = "$dev_rev" ]; then
		echo "Fan FW revs match, no need to update!"
		ret_val=1
	fi
	return $ret_val
}

check_current_version() {
	#
	# get current version on fan
	#
	installed_version=`/usr/local/bin/fan_controller $fan_num version | grep  Version: | awk '{print $2}'`
	prefix=`echo $installed_version | cut -c1`
	if [ "$prefix" != "F" ]; then
	    echo "Error retrieving current version"
	    exit 1
	fi
	echo "Checking current fan firmware version on $fan_num... $installed_version"

	operating_mode=`echo $installed_version |cut -c2-2`
	#echo "mode: $operating_mode"

	minor_rev=`echo $installed_version | cut -c5-5`
	#echo "rev: $minor_rev"

}

check_if_in_boot_mode() {
	#
	# get current version on fan
	#
	installed_version=`/usr/local/bin/fan_controller $fan_num version | grep Version | awk '{print $2}'`

	#echo "installed version: $installed_version"

	operating_mode=`echo $installed_version | cut -c2-2`
	#echo "mode: $operating_mode"

	if [ "$operating_mode" != "B" ]; then
	    # retry once
		installed_version=`/usr/local/bin/fan_controller $fan_num version | grep Version: | awk '{print $2}'`
		operating_mode=`echo $installed_version |cut -c2-2`
		if [ "$operating_mode" != "B" ]; then
	    	echo "Must be in boot mode"
	    	exit 1
		fi
	fi
}

check_if_in_controller_mode() {
	#
	# get current version on fan
	#
	installed_version=`/usr/local/bin/fan_controller $fan_num version | grep Version: | awk '{print $2}'`
	#echo "installed version: $installed_version"

	operating_mode=`echo $installed_version |cut -c2-2`
	#echo "mode: $operating_mode"

	if [ "$operating_mode" != "C" ]; then
	    # retry once
		installed_version=`/usr/local/bin/fan_controller $fan_num version | grep Version: | awk '{print $2}'`
		operating_mode=`echo $installed_version |cut -c2-2`
		if [ "$operating_mode" != "C" ]; then
	    	echo "Must be in controller mode"
	    	exit 1
		fi
	fi
}

find_upgrade_firmware() {
	#
	# find upgrade firmware in /firmware
	#

	new_firmware_name=`ls -L /firmware/$platform/fan |grep "fan_firmware" | grep -v boot | sort | tail -n 1 `
	if [ "$new_firmware_name" == "" ]; then
	    echo "Can't find new firmware in /firmware/$platform/fan"
	    exit 1
	fi

	echo "Locating new firmware... $new_firmware_name"
	new_firmware_name="/firmware/$platform/fan/$new_firmware_name"
}

find_upgrade_boot() {
	#
	# find upgrade boot in /firmware
	#

	new_boot_name=`ls -L /firmware/$platform/fan |grep "fan_firmware" | grep boot | sort | tail -n 1`
	if [ "$new_boot_name" == "" ]; then
	    echo "Can't find new boot in /firmware/$platform/fan"
	    exit 1
	fi

	echo "Locating new boot... $new_boot_name"
	new_boot_name="/firmware/$platform/fan/$new_boot_name"
}

switch_to_boot_mode() {

	echo "Switching to bootloader"
	/usr/local/bin/fan_controller $fan_num jumpto_boot
	sleep 3 
}

switch_to_controller_mode() {

	echo "Switching to controller mode"
	/usr/local/bin/fan_controller $fan_num jumpto_firmware
	sleep 3 
}

controller_reset() {

	echo "Resetting controller $fan_num"
	/usr/local/bin/fan_controller $fan_num reset
	sleep 6 
	installed_version=$(/usr/local/bin/fan_controller $fan_num version | grep Version: | awk '{print $2}')
	prefix=$(echo $installed_version | cut -c1)
	if [ "$prefix" != "F" ]; then
	    echo "Resetting controller $fan_num again"
	    /usr/local/bin/fan_controller $fan_num reset
	    sleep 10 
	fi
}

erase_firmware() {

	echo "Erasing firmware..."
	/usr/local/bin/fan_controller $fan_num erase_firmware

	if [ $? -eq 1 ]; then
	    echo "Failure erasing firmware"
	    exit 1
	fi
}

erase_boot() {

	echo "Erasing boot..."
	/usr/local/bin/fan_controller $fan_num erase_boot

	if [ $? -eq 1 ]; then
	    echo "Failure erasing boot"
	    exit 1
	fi
}

program_firmware() {

	echo "Programming firmware... "
	/usr/local/bin/fan_controller $fan_num program_firmware $new_firmware_name

	if [ $? -eq 1 ]; then
	    echo "Failure programming firmware"
	    exit 1
	fi
}

program_boot() {

	echo "Programming boot..."
	/usr/local/bin/fan_controller $fan_num program_boot $new_boot_name

	if [ $? -eq 1 ]; then
	    echo "Failure programming boot"
	    exit 1
	fi
}


usage() {
    echo "Usage:  $0 [option] <fan module number>"
    echo "           Options:"
    echo "           -a: All images (firmware and boot)"
    echo "           -b: Only the boot image"
    echo "           -f: Only the firmware image"
    echo ""
        echo "           <fan module number> is 1, 2, or 3"
    exit 1
}

platform=$(cat /var/run/platform)
if [ $platform != "RazorL" ] ; then
    echo "Command not applicable on this platform"
    exit 1
fi

if [ $# -lt 1 ]; then
    usage
else
	while getopts abf c 
	do
		case $c in
			a)
				UPDATE_BOOT=1
				UPDATE_FIRMWARE=1
				;;
			b)
				UPDATE_BOOT=1
				;;
			f)
				UPDATE_FIRMWARE=1
				;;
			*)
				usage
				;;	
		esac
		shift
	done
fi

if [ $UPDATE_BOOT == 0 ] && [ $UPDATE_FIRMWARE == 0 ]; then
    echo "No options given. Nothing to do."
    exit 1
fi

#
# first argument is fan module number
#
fan_num=$1
    max_fan=3

if [ $fan_num -lt 1 ] || [ $fan_num -gt 3 ]; then
	usage
fi


#  
# convert to [module][position] nomenclature
#
# shift module to first byte
fan_num=`expr $fan_num \* 10`
# add in fan position
fan_num=`expr $fan_num + 1`
echo "Programming could take a minute or so"
if [ $UPDATE_FIRMWARE == 1 ]; then
	
	controller_reset

	check_current_version

	find_upgrade_firmware

	compare_revision 0
	ret_val=$?
	if [ $ret_val -ne 1 ]; then

		switch_to_boot_mode


		check_if_in_boot_mode


		check_current_version


		erase_firmware


		program_firmware


		switch_to_controller_mode
	fi

#	controller_reset

	#
	# add 1 to fan number to get address of 'partner' controller
	#
	fan_num=`expr $fan_num + 1`

	    controller_reset

        check_current_version


        find_upgrade_firmware

	compare_revision 0
	ret_val=$?
	if [ $ret_val -ne 1 ]; then
		switch_to_boot_mode


		check_if_in_boot_mode


        	check_current_version


        	erase_firmware


		program_firmware


		switch_to_controller_mode
	fi
#	controller_reset

	#
	# subtract 1 to fan number to restore address of 'primary' controller
	#
	fan_num=`expr $fan_num - 1`
fi

if [ $UPDATE_BOOT == 1 ]; then
	
	controller_reset

	check_current_version

	find_upgrade_boot

	compare_revision 1
	ret_val=$?
	if [ $ret_val -ne 1 ]; then
	
		switch_to_controller_mode

		check_if_in_controller_mode

		check_current_version

		erase_boot

		program_boot
	fi

#	controller_reset
	
	#
	# add 1 to fan number to get address of 'partner' controller
	#
	fan_num=`expr $fan_num + 1`

	controller_reset

	check_current_version

	find_upgrade_boot

	compare_revision 1
	ret_val=$?
	if [ $ret_val -ne 1 ]; then
	
		switch_to_controller_mode

		check_if_in_controller_mode

		check_current_version

		erase_boot

		program_boot
	fi

#	controller_reset
	
	#
	# subtract 1 to fan number to restore address of 'primary' controller
	#
	fan_num=`expr $fan_num - 1`

fi

echo "Done"
