#!/bin/bash

# Setup these variables for this script
application="ProteusApp"
recoveryfile="ccu-recovery.sh"
fileUSBA="/mnt/remusb0/$recoveryfile"
fileUSBB="/mnt/remusb1/$recoveryfile"

compressedfile="ccu-recovery.file"
compressedFileUSBA="/mnt/remusb0/$compressedfile"
compressedFileUSBB="/mnt/remusb1/$compressedfile"
extractfolderUSBA="/mnt/remusb0/.tmp-ccu-recovery"
extractfolderUSBB="/mnt/remusb1/.tmp-ccu-recovery"
extractedFileUSBA="$extractfolderUSBA/$recoveryfile"
extractedFileUSBB="$extractfolderUSBB/$recoveryfile"

SCRIPT_NAME="$(basename "$0")"
ARGS="$@"
UPDATE_FILE="$SCRIPT_NAME.update"
UPDATE_FILE_VERIFICATION="$UPDATE_FILE.md5"
VERSION="2.1"

DELAY_FLAG_FILE=".showdebugdelay.flag"
DEBUG_FLAG_FILE=".showdebug.flag"
OUTPUT_ON_SCREEN=0

###############################################################################
###############################################################################
###############################################################################
# CHECK THE ARGS BEFORE WE DO ANYTHING
###############################################################################
###############################################################################
###############################################################################

while test $# -gt 0; do
	case "$1" in
		-h|--help)
						echo "$application - Proteus Starter script"
						echo " "
						echo "$application [options]"
						echo " "
						echo "options:"
						echo "-h, --help          show brief help"
						echo "-v, --version       echo version"
						exit 0
						;;
		-v|--version)
						csumProteus=$(md5sum Proteus | awk '{ print $1 }' | tail -c 8)
						csumProteusApp=$(md5sum ProteusApp | awk '{ print $1 }' | tail -c 8)
						echo "Proteus: $VERSION sh:[$csumProteus] bin:[$csumProteusApp]" > /dev/tty1
						echo "Proteus: $VERSION sh:[$csumProteus] bin:[$csumProteusApp]"
						exit 0
						;;
		*)
						break
						;;
	esac
done

###############################################################################
###############################################################################
###############################################################################
# FUNCTIONS BELOW
###############################################################################
###############################################################################
###############################################################################

function printVersions () {
	line=$(head -1 UDProteus)
	if [[ $line == *"#!/bin/bash"* ]]; then
		echo "UDProteus: Start script installed!" > /dev/tty1
		echo "UDProteus: Start script installed!"
	else
		echo "UDProteus: Start script not installed!" > /dev/tty1
		echo "UDProteus: Start script not installed!"
	fi
	
	csumProteus=$(md5sum Proteus | awk '{ print $1 }' | tail -c 8)
	csumProteusApp=$(md5sum ProteusApp | awk '{ print $1 }' | tail -c 8)
	csumStartup=$(md5sum startup.sh | awk '{ print $1 }' | tail -c 8)
	csumSamba=$(md5sum startSamba.sh | awk '{ print $1 }' | tail -c 8)
	csumUDProteus=$(md5sum UDProteus | awk '{ print $1 }' | tail -c 8)
	csumUDProteusApp=$(md5sum UDProteusApp | awk '{ print $1 }' | tail -c 8)
	
	
	echo "Version info:"
	echo "Proteus: $VERSION sh:[$csumProteus] bin:[$csumProteusApp]" > /dev/tty1
	echo "Proteus: $VERSION sh:[$csumProteus] bin:[$csumProteusApp]"
	
	echo "UDProteus: Hash:[$csumUDProteus]" > /dev/tty1
	echo "UDProteus: Hash:[$csumUDProteus]"
	
	echo "UDProteusApp: Hash:[$csumUDProteusApp]" > /dev/tty1
	echo "UDProteusApp: Hash:[$csumUDProteusApp]"
	
	echo "Startup: sh:[$csumStartup]" > /dev/tty1
	echo "Startup: sh:[$csumStartup]"
	
	echo "StartSamba: sh:[$csumSamba]" > /dev/tty1
	echo "StartSamba: sh:[$csumSamba]"
}

function debugMsg () {
	echo "[DEBUG] $1" # debug on the normal console 
	
	if [ $OUTPUT_ON_SCREEN == 1 ]
	then
		echo "[DEBUG] $1" > /dev/tty1 # debug on the screen
	fi
}

function setDebugDelay () {
	touch $DELAY_FLAG_FILE
	OUTPUT_ON_SCREEN=1
}

function clearDebugDelay () {
	rm -f $DELAY_FLAG_FILE
}

# Check for a magic file to enable debug output
function checkToShowDebug () {
	mount /dev/sda1 /mnt/remusb0
	mount /dev/sdb1 /mnt/remusb1
	
	if [ -f "$DEBUG_FLAG_FILE" ]
	then 
		OUTPUT_ON_SCREEN=1
	fi
	
	if [ -f "/mnt/remusb0/$DEBUG_FLAG_FILE" ]
	then 
		OUTPUT_ON_SCREEN=1
	fi
	
	if [ -f "/mnt/remusb1/$DEBUG_FLAG_FILE" ]
	then 
		OUTPUT_ON_SCREEN=1
	fi
	
	if [ $OUTPUT_ON_SCREEN == 1 ]
	then
		debugMsg "Debug mode enabled by file"
	fi	
		
	umount /dev/sda1 /mnt/remusb0
	umount /dev/sdb1 /mnt/remusb1
}

# This function uses an MD5 checksum to verify a file
# Params:
# $1 MD5 checksum list file
# Returns:
# 0 - Files verify ok
# 1 - File verification failure
# 2 - Checksum file not found
function verifyFilesMD5 () {
	CHECKSUMFILE=$1
	
	if [ -f $CHECKSUMFILE ]
	then
		md5sum -c -s $CHECKSUMFILE
		return $?
	else
		return 2
	fi
}

function checkSelfUpgrade () {
  # check if there is a new version of this file
  # here, hypothetically we check if a file exists in the disk.
  # it could be an apt/yum check or whatever...
  if [ -f "$UPDATE_FILE" ]
	then
	  setDebugDelay
    # install a new version of this file or package
    debugMsg "Found a new script update, verifying ..."
		
		verifyFilesMD5 $UPDATE_FILE_VERIFICATION
		
		if [ $? ]
		then
			debugMsg "Verificaition failed, self update aborted."
			mv $UPDATE_FILE $UPDATE_FILE.vfailed
			mv $UPDATE_FILE_VERIFICATION $UPDATE_FILE_VERIFICATION.vfailed
			return
		fi
		
		debugMsg "Verification success, self updating ..."
    install "$UPDATE_FILE" "$SCRIPT_NAME"
    rm -f "$UPDATE_FILE"
		rm -f "$UPDATE_FILE_VERIFICATION"
 
    # note that at this point this file was overwritten in the disk
    # now run this very own file, in its new version!
    debugMsg "Running the new version ..."
    ( ./$SCRIPT_NAME $ARGS )
 
    # now exit this old instance
    exit 0
	fi
}

function checkUSBforRecovery () {
	debugMsg "Checking for a recovery file on USB A / B"
	# Lets mount both the USB drives to look for our recovery file
	mount /dev/sda1 /mnt/remusb0
	mount /dev/sdb1 /mnt/remusb1

	RC=0
	
	# Check for plain script located in the root of USB A
	# Run if found
	if [ -f "$fileUSBA" ]
	then
		debugMsg "$fileUSBA found. Running ..."
		( $fileUSBA )
		RC=$?
		setDebugDelay
		
	# Check for plain script located in the root of USB B
	# Run if found
	elif [ -f "$fileUSBB" ]
	then
		debugMsg "$fileUSBB found. Running ..."
		( $fileUSBB )
		RC=$?
		setDebugDelay
		
	# Check for a compressed folder on USB A
	# Extract and run if found
	elif [ -f "$compressedFileUSBA" ]
	then
		debugMsg "$compressedFileUSBA found. Extracting ..."
		mkdir $extractfolderUSBA
		unzip -q -o $compressedFileUSBA -d $extractfolderUSBA
		debugMsg "Running ..."
		( $extractedFileUSBA )
		rm -rf $extractfolderUSBA
		RC=$?
		setDebugDelay
		
	# Check for a compressed folder on USB B
	# Extract and run if found
	elif [ -f "$compressedFileUSBB" ]
	then
		debugMsg "$compressedFileUSBB found. Extracting ..."
		mkdir $extractfolderUSBB
		unzip -q -o $compressedFileUSBB -d $extractfolderUSBB
		debugMsg "Running ..."
		( $extractedFileUSBB )
		rm -rf $extractfolderUSBB
		RC=$?
		setDebugDelay
		
	# No recovery files found
	else
		debugMsg "$recoveryfile not found."
	fi

	umount /dev/sda1 /mnt/remusb0
	umount /dev/sdb1 /mnt/remusb1

	# Deal with the various return codes that could have been returned
	if [ $RC == 3 ]
	then
		debugMsg "Script returned code 3 - exit without running application"
		sleep 2
		exit $RC
	fi

	if [ $RC == 4 ]
		then
		debugMsg "Script retuned code 4 - rebooting linux"
		sleep 2
		reboot
	fi
	
	if [ $RC == 5 ]
	then
		debugMsg "Script retuned code 5 - restarting this script"
		( ./$SCRIPT_NAME $ARGS )
		sleep 2
    # now exit this old instance
    exit 0
	fi
}

function checkForApplicationUpdate {
	if [ -f "$application.update" ]
	then 
		setDebugDelay
		debugMsg "$application update found, installing ..."
		mv $application.update $application
		sync
	fi
}




function main () {
	printVersions

	checkToShowDebug

	checkSelfUpgrade

	debugMsg "$application Application Script V$VERSION"

	checkUSBforRecovery

	checkForApplicationUpdate
    
    # Disable kernel printk messages (only level 0-1 stays) to avoid dropping serial characters from Hcs12
    dmesg -n 2

	#
	# Lets get on with booting the application now
	#

	# This files lets us run a debug Proteus app under GDB.
	# In the event of a segfault we should get some useful output

	debugMsg "Launching $application running with core dumping"

	#lets make sure the app is executeable
	chmod 777 $application

	# let core dumps happen
	ulimit -c unlimited
	
	if [ -f "$DELAY_FLAG_FILE" ]
	then
		clearDebugDelay
		debugMsg "Application will launch in 10 seconds ..."
		sleep 7 # give the user time to see the debug
	fi
	
	# launch GDB and run ProteusApp
	# gdb -quiet -ex "run" ProteusApp
	sleep 3
	./$application $ARGS
}

# Execute the script main function
main
