#!/bin/sh
#########################################################################################
# Hager application automatic starting
#
# Versions
#
# 1.0.1
# StartFramework function modified to launch with "knxng" profile instead of "knxng-dev"
# used before
#
# 1.0.2
# Install a supervision mechanism aroud the framework starting. The power led's color
# reflect the result of the framework launching. 
#
# 1.0.3
# Use a new SetLed function provided by an updated version of the"update_common" file that
# must be >= 1.0.8
#
# 1.0.4 
# The script gets its own version and don't share the SCRIPT_VERSION variable anymore
# Add a missing define : START_SURVEY that it used to launch the update_survey script 
# for the first time
#
# 1.0.5
# Add a control on StartUpdateSurvey so that the daemon can't be started twice
#
# 1.0.6
# Add of a GetjavaDirectory function which allow a dynamic adaptation of the VM_HOME variable
# depending on the directory name which will change according to the JRE version, for instance 
# moving from a 1.7.045 to a 1.8.051
# Add of a distinctive part in logs messages
#
# 1.0.7
# Changes in the inotfywait treatment to better manage different execution return codes
#
# 1.0.8
# Integration of EMSS specificities
# 
# 1.1.0
# Add the management of HSB/EMMS plateforms
#
# 1.1.1
# Modify the way to launch the update_survey daemon as it must be launched in any case, 
# even if the application software doesn't start, and that was not the case in previous 
# version
#########################################################################################

APPLICATION_SCRIPT_VERSION="1.1.1"
APPLICATION_SCRIPT_INITIALS="[APP]"

source /usr/local/bin/update_common
source /etc/gpio/GPIO_common

#########################################################################################
# Local variables defined
#########################################################################################

CONSOLE=/dev/console

UPDATE_DIR="/tmp/update"
SOFTWARE_STATE_DIR=$UPDATE_DIR/platformstate

STARTED_STATUS_FILE="/tmp/AppStatus"

APP_START_FILE="started"

PATH_TO_SURVEY=$SOFTWARE_STATE_DIR

NORMAL_START="NormalStart"
UPDATED_START="UpdatedStart"

INOTIFY_OPT_TIMEOUT="-r -e close_write -e moved_to -t 90"

START_SURVEY="start_survey"

#------------------ LogFiles defines

LOG_DEBUG=1
LOG_WARNING=2
LOG_NORMAL=3

LOGFILE_AND_CONSOLE="Console"

#------------------ Status defines

STATUS_WAIT_APP=4
STATUS_APP_STARTED=5

#------------------ Inotifywait defines

INOTIFY_RET_EVENT=0
INOTIFY_RET_ERROR=1
INOTIFY_RET_TIMEOUT=2

#------------------ Hardware dependent defines

KNX_MBSA_START="knxng_mbsa_start"
EMSS_MBSA_START="emss_mbsa_start"

KNX_APP_NAME="knxng"
KNX_APP_PROFILE="knxng"

EMSS_APP_NAME="emss"
EMSS_APP_PROFILE="emss-dev"

APP_MBSA_START=""
APP_NAME=""
APP_PROFILE=""

#########################################################################################
# Fonctions
#########################################################################################

###########################################################################################
# Function that add the initials of the script to each message that will be logged.
# That makes the reading of the logs unambiguous

WriteLog() {
	LogUpdate "$APPLICATION_SCRIPT_INITIALS : $1" $2 $3
}

#########################################################################################
# Function that set correct defines according to the current board type

Application_Init() {

	# Init hardware specific defines
	boardtype=$(Get_BoardType)
 	LogUpdate "$boardtype board detected"

 	case "$boardtype" in

 		$KNX_BOARD)
			APP_MBSA_START=$KNX_MBSA_START
			APP_NAME=$KNX_APP_NAME
			APP_PROFILE=$KNX_APP_PROFILE
			;;

		$EMSS_BOARD)
			APP_MBSA_START=$EMSS_MBSA_START
			APP_NAME=$EMSS_APP_NAME
			APP_PROFILE=$EMSS_APP_PROFILE
			;;

		*)
			return 1
			;;

	esac

	return 0
}

#########################################################################################
# Function that return the JRE directory in order to set the JAVA_HOME variable
# Normally this directory should be located under /usr/bin but there is no guarantee
# that it will not move in the future.
# The process look at the root part of the directory which must be in the form of 
# ejreX.Y.Z_aa where X.Y.Z.aa represent the version number of the JRE.

Get_JavaDirectory() {

	BASE_JRE="ejre"
	result=$(find / -type d -name $BASE_JRE*) 2> /dev/null

	echo $result
}

#########################################################################################
# Function for setting internal status 
#
# Order of parameters
# $1 Status to set 

SetStartedStatus() {
	if [ ! -z "$1" ]; then
		echo "$1" > $STARTED_STATUS_FILE
	fi
}

#########################################################################################
# Function to get internal status 

GetStartedStatus() {
	startedStatus=$(cat $STARTED_STATUS_FILE)
}

#########################################################################################
StartFramework() {
	
	case $1 in

		$NORMAL_START)
			
			LogUpdate "Starting Hager application ..." $LOG_NORMAL $LOGFILE_AND_CONSOLE
			;;

		$UPDATED_START)
			LogUpdate "Starting updated Hager application ..." $LOG_NORMAL $LOGFILE_AND_CONSOLE
			;;

		*)
			;;
	esac

	cd /root/app/mbsa/bin

	LogUpdate "Launching ./$APP_MBSA_START $APP_PROFILE from $(pwd)"
	nohup sh ./$APP_MBSA_START $APP_PROFILE > /tmp/mbsa.log 2>&1 &
}
 
#########################################################################################
StopFramework() {

	LogUpdate "Stopping Hager application ..." $LOG_NORMAL $LOGFILE_AND_CONSOLE
	LedOrange 1
	sleep 1
		
	sh /root/app/mbsa/bin/mbsa_stop

	LogUpdate "Hager application stopped" $LOG_NORMAL $LOGFILE_AND_CONSOLE
	LedRed 1
		
	ps | grep $APP_NAME | grep -v grep | awk '{print $1}' | xargs kill -9
}

#########################################################################################
StartUpdateSurvey() {

	if ! IsProcessRunning $START_SURVEY; then
		
		LogUpdate "Starting software update survey ..." 

		cd /usr/local/bin
		nohup sh ./update_survey $START_SURVEY > /dev/null 2>&1 &
	else
		LogUpdate "Software update survey already running" $LOG_NORMAL $LOGFILE_AND_CONSOLE
	fi
} 

#########################################################################################
# Function that looks on events happening on $SOFTWARE_STATE_DIR and sub-directories
#
# Creation of a so called "started" file in $SOFTWARE_STATE_DIR
# 	- Means an application starting status is signified
#
# Order of parameters
# $1 = filename
# $2 = filepath
# $3 = event

WhatHappensinSoftwareStateDir() {
	
	LogUpdate "Event $3 on $1 file in $2 directory"

	case "$2" in
	
		$UPDATE_STATE_DIR/)
		
			if [ "$1" == $APP_START_FILE ]; then
				SetStartedStatus $STATUS_APP_STARTED
			fi
						
			;;
			
		*)
			# LogUpdate "Function WhatHappensinUpdateDir - Event from $2"
			;;
	
	esac
}

#########################################################################################
#########################################################################################
# Script beginning
#########################################################################################

LogUpdate "----------------------------- $(basename "$0") ($1) - v$APPLICATION_SCRIPT_VERSION (using library $UPDATE_COMMON_SCRIPT_VERSION) - started" $LOG_NORMAL $LOGFILE_AND_CONSOLE

Application_Init

##### Create working directories if necessary
ManageUpdateDirectories

if [ ! -d "$SOFTWARE_STATE_DIR" ] ; then
	LogUpdate "Creating $SOFTWARE_STATE_DIR directory"																				# Create $SOFTWARE_UPDATE_DIR
	CreateDirectory $SOFTWARE_STATE_DIR																								# As it is necessary to update the software
fi

##### Try to detect JRE location to set the JAVA_HOME variable

result=$(Get_JavaDirectory)

if [ -z $result ]; then
	LogUpdate "Can't find JRE directory. VM_HOME unset. Abort"
	exit
fi

export VM_HOME=$result																												# JRE found, set the java environment variable
LogUpdate "VM_HOME environment variable set to $VM_HOME"

##### Look at kind of start

case "$1" in

	start)																															# Normal start when coming from booting process

		InitGpiosMonitoring
		StartFramework $NORMAL_START
		SetStartedStatus $STATUS_WAIT_APP


		inotifyOutput=$(inotifywait $INOTIFY_OPT_TIMEOUT --format '%f %e %w' $PATH_TO_SURVEY)										# Start a timed-out sleeping survey on some events that may happens in some directory
		retCode=$?

		case "$retCode" in

			$INOTIFY_RET_EVENT)

				echo $inotifyOutput | while read file event location
				do
					echo "Inotifywait event occurs"
					WhatHappensinSoftwareStateDir $file $location $event															# Function called in a child process, cause of pipe above
				done

				GetStartedStatus
				
				case "$startedStatus" in

					$STATUS_WAIT_APP)
						SetLed POWER RED FIXED
						;;

					$STATUS_APP_STARTED)
						SetLed POWER GREEN FIXED
						;;

					*)
						LogUpdate "What kind of updateStatus is it : $updateStatus"
						;;

				esac

				;;

			$INOTIFY_RET_ERROR)
				LogUpdate "Inotifywait returns an error."
				;;

			$INOTIFY_RET_TIMEOUT)
				LogUpdate "Inotifywait timeout expires"
				;;

			*)
				LogUpdate "Unexpected inotifywait return code : $retCode"
				;;

		esac

		# Must start the update survey "daemon" in any case
		StartUpdateSurvey
		;;

	stop)

		StopFramework

		;;

	restart)
        StopFramework
        StartFramework $NORMAL_START
        ;;
 
    update)
		StartFramework $UPDATED_START
		;;
	
	*)
        LogUpdate "Usage: $0 { start | stop | restart }" $LOG_NORMAL $LOGFILE_AND_CONSOLE
        exit 1
        ;;
	
esac

LogUpdate "----------------------------- $(basename "$0") - v$APPLICATION_SCRIPT_VERSION - ended" $LOG_NORMAL $LOGFILE_AND_CONSOLE

exit $?


