#!/bin/sh

# Perform flashing for staged images (if any)
# Only the most recent image gets flashed, everything else is
# removed with a warning.

# Scheduled updates are to be collected from here:
STAGING_DIR=/var/lib/softupd/staging

# Command to actually flash images
CMD_DO_FLASH="/usr/bin/flasher --local -f -F"

SOFTUPD_LOG="/var/log/softupd.log"
SOFTUPD_PID="/var/run/softupd.pid"

CMT_RESET="/usr/sbin/cmt-factory-reset"

# set -e

softupstart() {
	( awk -vwhat="$2" -f /usr/lib/softupstart.awk /etc/event.d/$1 | grep -v BACKLIGHT | sh )
}

softupd_start() {
	echo "Starting stuff for softupd"
	mount -t proc none /proc
	mount -t sysfs none /sys
	# for dsme
	modprobe omap_wdt
	modprobe twl4030_wdt
	# for bme
	modprobe leds_lp5523
	# for softupd
	modprobe ssi_char

	for d in twl4030_wdt watchdog ssi; do
		if [ -e /dev/$d ]; then
			rm -f /dev/$d
		fi
	done

	mknod /dev/twl4030_wdt c 10 142
	mknod /dev/watchdog c 10 130

	if [ -e /dev/ssi ]; then
		rm -f /dev/ssi
	fi
	maj=$(grep ssi_char$ /proc/devices | cut -d' ' -f1)
	mknod /dev/ssi c $maj 0

	# if we have to perform flashing, we need to do a minimal startup
	softupstart dsme
	softupstart bme pre-start
	softupstart bme
	# and softupd
	ifconfig lo 127.0.0.1 up
	/usr/sbin/softupd --local --log=$SOFTUPD_LOG --standalone \
		--daemonize -vv
}

do_reboot() {
	sync
	reboot -f
}

is_cmt_image() {
	local image="$1"

	echo "$image" | grep "cmtImage"
}

draw_log() {
	bg_color=0xffff
	text_color=0xf000
	y=0
	line_height=20
	text2screen -c -x 0 -y 0 -w 800 -h 480
	tail -24 $SOFTUPD_LOG | cut -c 21- | while read line ; do
		text2screen -t "$line" -s 2 -x 0 -y $y \
			-T $text_color -B $bg_color
		y=$(($y + $line_height))
	done
	sleep 5
}

handle_flash_failure() {
	# if flashing fails, reboot and try again
	echo "Flashing failed, log follows:"
	tail -500 $SOFTUPD_LOG

#	draw_log

	do_reboot
}


if [ ! -e "$STAGING_DIR" ]; then
	# staging dir doesn't exist, so much easier for us
	exit 0
fi

images=$(ls -t $STAGING_DIR)

for i in $images; do
	__image="$STAGING_DIR/$i"
	att_file="$STAGING_DIR"/../"$i".attempts
	if [ -n "$flashed_once" ]; then
		echo "Warning: $__image is not going to be flashed, removing."
		rm -f "$__image" "$att_file"
		continue
	fi

	if [ -r "$att_file" ]; then
		attempts=$(cat "$att_file")
	else
		rm -f "$att_file"
		attempts=0
	fi

	attempts=$(($attempts + 1))
	if [ $attempts -gt 5 ]; then
		echo "Too many flashing attempts. Nuking $__image."
		rm -f "$__image" "$att_file"
		do_reboot
	fi
	echo $attempts > "$att_file"

	softupd_start

	echo "Flashing $__image."
	$CMD_DO_FLASH "$__image"
	ret=$?

	if [ -r $SOFTUPD_PID ]; then
		kill -TERM $(cat $SOFTUPD_PID)
		# wait a while for softupd to finish
		c=0
		while [ -r $SOFTUPD_PID -a $c -lt 4 ]; do
			c=$(($c+1))
			sleep 1
		done
	fi

	if [ $ret = 0 ]; then
		if is_cmt_image "$__image" && [ -x $CMT_RESET ]; then
			$CMT_RESET
			ret=$?
			[ $ret = 0 ] || echo "CMT reset failed"
		fi
	fi

	# failing to flash will leave the fiasco behind, but will
	# remove staging symlink so as to avoid reboot loop
	if [ $ret = 0 ]; then
		if [ -L "$__image" ]; then
			rm -f $(readlink "$__image")
		fi
		rm -f "$__image" "$att_file"
	else
		handle_flash_failure
	fi

	flashed_once=1
done

if [ -n "$flashed_once" ]; then
	do_reboot
fi
