#!/bin/sh
#
# VARIABLES INITIALISATION
##########################
# timeout in second
defaultTimeout=5
# sleeptime in microsecond
defaultSleeptime=1000000

esc=$'\x1b'
attr=${attr:-$esc[32m} default=${default:-$esc[0m} # to retore vim colors: ]}]}
PS4="+${attr}$$:${default} "

#
# FUNCTION DEFINITION
#####################
echoerror () {
    echo "$@" >&2
}

# in the different scripts, only arg_summary and arg_help are to be defined.
help() {
    local - helpmsg RET=0
    
    # display the header or not depending if we are called directly or from a script
    if [[ -z "${HELPPREFIX:=}" ]]; then
         helpmsg="\nSyntax: "
    else
         helpmsg="$HELPPREFIX"
    fi
    helpmsg="${helpmsg}${0##*/}"
    [[ -z "$HELPPREFIX" ]] && helpmsg="${helpmsg} [-w|--wait]"
    helpmsg="${helpmsg} [-h|--help]${arg_summary:+ $arg_summary}\n"
    [[ -z "$HELPPREFIX" ]] && helpmsg="${helpmsg}\n$arg_help\n"

    printf "$helpmsg"
    return $RET
}

senddbus() {
    local - signal="$1"; shift
    dbus-send /Platform com.alcatel.ICTouch.ICTInterface.$signal "$@"
    return $? 
}

getfirsttmpfile() {
    local - nextfile file="$1"
    nextfile="$(ls -t $file* 2>/dev/null | tail -n 1)"
    [[ -z "$nextfile" ]] && return 1
    echo "$nextfile"
    return 0
}

getlasttmpfile() {
    local - nextfile file="$1"
    nextfile="$(ls -rt $file* 2>/dev/null | tail -n 1)"
    [[ -z "$nextfile" ]] && return 1
    echo "$nextfile"
    return 0
}

stampfile() {
    local - ts filenots file="$1" newfile 
    set +vx

    # get the last part of the filename 
    ts=${file##*.ts_}
    # check if it is a timestamp
    [[ -n "${ts//[[:digit:]]}" ]] && ts="" || ts=".ts_$ts"
    filenots=${file/$ts}
    newfile=$filenots.ts_$(date +%s -r $file)
    mv $file $newfile
    echo "$newfile"
    return 0
}

getnexttmpfile() {
    local - file="$1" 
    ts=$(date +%s)
    echo "$file.ts_$(date +%s)"
    return 0
}

isRunning() {
   local - tmpfileseed="$1" runfile
   
   runfile=/tmp/.${tmpfileseed##*/}.running
   [ -f /tmp/.${tmpfileseed##*/}.running ] && return 0 || return 1
}

send() {
    local - wait=$1 tmpfileseed=$2 timeout=$3 RET=0 tmpfile tmpfile_ts ts time=0 runfile; shift 2
    
    : "${attr}verify that the timeout is a true timeout${default}"
    [[ "${timeout}" == "${timeout//[^[:digit:]]}" ]] && shift || timeout=$defaultTimeout

    : "${attr}verify the parameters${default}"
    [[ $wait -eq 1 ]] && [[ -z "$tmpfile" ]] && RET=1 && return $RET
    sleeptime=${sleeptime:-$defaultSleeptime}

    RET=$?
    [ $RET -ne 0 ] && return $RET

    # The wait mecanism is based on tmpfile
    # 1) get the timestamp of the tmpfile
    # 2) wait at most timeout for the tmpfile to be touch
    # 3) at the end of the timeout if the tmpfile has not been touched, it is an error
    # 4) if the file has been touched, that means that it is being processed, wait for its removal

    if [[ $wait -eq 1 ]]; then
        runfile=/tmp/.${tmpfileseed##*/}.running
    	touch $runfile
	: "${attr}wait => get timestamp${default}"
        tmpfile=$(getfirsttmpfile $tmpfileseed)
        mv $runfile /tmp/.${tmpfile##*/}.running
        runfile=/tmp/.${tmpfile##*/}.running
        echo "link: $(readlink $tmpfile)" >> $runfile
        while [[ $? -eq 0 ]]; do
	    tmpfile=$(stampfile $tmpfile)
            : "${attr}get the original timestamp${default}"
            ts=${tmpfile##*.ts_}
            tmpfile_ts=$ts
	    mv $tmpfile $tmpfileseed
	    tmpfile=$tmpfileseed

            : "${attr}send the message${default}"
            senddbus "$@"
            
            : "${attr}wait at most timeout${default}"
            time=$(date +%s)
            printf "TIME: $time	TIMESTAMP: $ts		TIMEOUT: $timeout\n" >> $runfile
            timeout=$(($time+$timeout))
       	    printf "time: $time	timestamp: $ts		timeout: $timeout\n" >> $runfile
            while [ ${ts//[![:digit:]]} -eq $tmpfile_ts ] && [ $time -lt $timeout ] && [ -e $tmpfile ]; do
                usleep $sleeptime
                [ -e $tmpfile ] && ts=$(date +%s -r $tmpfile) || ts="removed(0)"
	        time=$(date +%s)
	 	printf "time: $time	timestamp: $ts	timeout: $timeout\n" >> $runfile
            done
            : "${attr}if tmpfile still exist and the the timestamp has changed, wait for the file to be removed${default}"
            if [ -e $tmpfile ]; then
            	if [ $ts -ne $tmpfile_ts ]; then
                    : "${attr}wait for the tmpfile to be removed${default}"
                    while [ -e $tmpfile ]; do
                        usleep $sleeptime
                    done 
                else
            	    rm $tmpfile
                    echoerror "Timeout reached, noone has started to process $tmpfile."
                    RET=1
                fi
            fi
            : "${attr}look for any remaining tmpfile${default}"
            tmpfile=$(getfirsttmpfile $tmpfileseed)
        done
        mv $runfile ${runfile/running/done}
    else
        : "${attr}send the message${default}"
        senddbus "$@"
    fi
    return $RET
}
