#!/bin/bash

if [[ -x "/usr/local/bin/setled" ]]; then
	setled="/usr/local/bin/setled"
else
	setled="/bin/true"
fi

update_count=0

log()
{
	echo "NIP Update - $1" > /dev/kmsg
}

kill_nipexec()
{
	if [[ -e "/var/run/nipexec.pid" ]] ; then
	    service rppl-nip stop
	    ${setled} 2
	fi

	#if it didn't stop kill with extreme prejudice
	pid=$(pidof nipexec)
	if (( $? == 0 )) ; then
		log "Forcefully terminating nipexec (${pid})"
		kill -KILL ${pid}
		rm -f /var/run/nipexec.pid
		${setled} 5
	fi

	#stop nipexec from running
	echo "$$" > /var/run/nipexec.pid
}


#todo: better checking here
check_update()
{
	local update="$1"

	if [[ ! -r ${update} ]] ; then
		log "${update} invalid."
		return 1
	fi

	if [[ ! -f ${update} ]] ; then
		log "${update} is not a regular file."
		return 1
	fi

	fname=$(basename ${update})
	if [[ ${fname} != rppl-nip-update-* ]] ; then
		log "${update} is not a valid file"
		return 1
	fi

	return 0
}

install_update()
{
	local update="$1"

	log "installing update: ${update#*t/}"
	rm -rf /tmp/update
	mkdir -p /tmp/update
	${setled} 7
	tar -xvf ${update} -C /tmp/update > /dev/null

	sync

	if [[ -e /tmp/update/updexec ]]; then
		( cd /tmp/update ; ./updexec )
		if (( $? != 0 )) ; then
			return 1
		fi
	fi

	((update_count++))
	return 0
}


install_from_directory()
{
	local directory="${1%/}"

	mount -o remount,rw /

	for update in ${directory}/rppl-nip-update-*
	do
		if ! check_update ${update} ; then
			continue
		fi

		if ! install_update ${update} ; then
			log "update ${update} failed."
			break
		fi
	done

	rm -rf /tmp/*
	mount -o remount,ro /
}


check_directory_for_updates()
{
    local noglob=$(shopt nullglob | cut -f2)
    if [[ "$noglob" == "on" ]]; then
        shopt -u nullglob
    fi
    ls -dv $1/rppl-nip-update-* > /dev/null 2>&1
    rc=$?
    if [[ "$noglob" == "on" ]]; then
        shopt -s nullglob
    fi
    return $rc
}


main()
{
	if [[ -b $1 ]] ; then

		if ! mount -o ro $1 /mnt ; then
			log "Unable to mount device: $1"
			exit 1
		fi

		if ! check_directory_for_updates "/mnt" ; then
			umount /mnt
			log "No updates found on: $1"
			exit 1
		fi

		kill_nipexec
		install_from_directory "/mnt"
		umount /mnt

	elif [[ -d $1 ]] ; then

		if ! check_directory_for_updates "$1" ; then
			umount /mnt
			log "No updates found in: $1"
			exit 1
		fi

		kill_nipexec
		install_from_directory $1

	elif [[ -f $1 ]] ; then

		if ! check_update $1 ; then
			log "Not a valid update: $1"
			exit 1
		fi

		kill_nipexec
		install_update $1

	else
		log "Unable to update."
		exit 1
	fi

	${setled} 3

	if (( ${update_count} > 0 )) ; then
		halt
	fi
}

main "$@"
