#!/bin/bash

#============================================================================
# Copyright 2009-2017 ECMWF.
# This software is licensed under the terms of the Apache Licence version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.
#============================================================================

# Environment variables from the configuration step
ECFLOWUI_BT=no
ECFLOWUI_BT_EMAIL_ADDRESS_FILE=x
ECFLOWUI_VERSION=4.8.0
ECFLOWUI_INSTALLDIR=/usr
ECFLOWUI_USAGE_LOG=x
ECFLOWUI_SITE_TAG=x

# ----------------------------------------------------------
# Clean up the tmp directory at the end or on error
#-----------------------------------------------------------
cleanup(){
    status=$?
    trap "" EXIT ERR

    # restore stdout/stderr
    if [ x$ECFUI_SLOG != xyes ]
    then
        exec 1>&5
        exec 2>&6
    fi

    if [ "$status" -eq "0" ]
    then
        echo "$(basename $0): $1 (OK) (line $2), exit status $status, starting 'cleanup'"
    else
        status_message="$(basename $0): $1 on ERROR (line $2), exit status $status, starting 'cleanup'"
        echo $status_message

        if [ -e $ECFLOWUI_LOGFILE ] ; then

            TAILNUM=50
            UI_TAILNUM=50

            if [ $ECFLOWUI_BT != "no" ] ; then
                # find the backtrace tag if there
                btline=$(grep -n "Backtrace:" $ECFLOWUI_LOGFILE | cut -f1 --delimiter=':')
                gret=$?
                if [ "$gret" = "0" -a "x$btline" != "x" ] ; then
                    nlines=$(wc -l $ECFLOWUI_LOGFILE | cut -f1 --delimiter=' ')
                    TAILNUM=$(expr $nlines - $btline + 100)
                fi
            fi

            # Logic: ECFLOWUI_BT_EMAIL_ADDRESS_FILE is not set, then the log/backtrace
            # will go to stdout; otherwise it will be e-mailed to the
            # addresses instead (the user will not see the backtrace).

            if [ $ECFLOWUI_BT_EMAIL_ADDRESS_FILE != "x" ] ; then
                if [ -e $ECFLOWUI_BT_EMAIL_ADDRESS_FILE ] ; then
                    EFLOWUI_LOGTAIL="${ECFLOWUI_LOGFILE}.tail"
                    ecfuimsg="ecFlowUI backtrace from user $USER"
                    echo "Sending crash report by e-mail..."
                    echo "user/host          : $USER/$HOST"          >  $EFLOWUI_LOGTAIL
                    echo "ecflow version     : $ECFLOWUI_VERSION"    >> $EFLOWUI_LOGTAIL
                    echo "ecflow install dir : $ECFLOWUI_INSTALLDIR" >> $EFLOWUI_LOGTAIL
                    echo "start time         : $ECFLOWUI_STARTTIME"  >> $EFLOWUI_LOGTAIL
                    echo "stop time          : $(date)"              >> $EFLOWUI_LOGTAIL
                    echo ""                                          >> $EFLOWUI_LOGTAIL
                    echo $status_message                             >> $EFLOWUI_LOGTAIL
                    tail -$TAILNUM $ECFLOWUI_LOGFILE                 >> $EFLOWUI_LOGTAIL

                    #Add the last lines from the user interaction log file
                    if [ -e $ECFLOWUI_UI_LOGFILE ] ; then
                        echo ""                                      >> $EFLOWUI_LOGTAIL
                        echo "Last $UI_TAILNUM lines of user interaction log file:" >> $EFLOWUI_LOGTAIL
                        tail -${UI_TAILNUM} $ECFLOWUI_UI_LOGFILE     >> $EFLOWUI_LOGTAIL
                    fi

                    addr=$(head -1 $ECFLOWUI_BT_EMAIL_ADDRESS_FILE)
                    mail -s "$ecfuimsg"  $addr < $EFLOWUI_LOGTAIL
                    rm -f $EFLOWUI_LOGTAIL
                    echo "Report sent"
                else
                    echo "No report sent because e-mail address file does not exist: $ECFLOWUI_BT_EMAIL_ADDRESS_FILE"
                fi
            else
                echo "Last $TAILNUM lines of log file:"
                tail -$TAILNUM $ECFLOWUI_LOGFILE

                #Add the last lines from the user interaction log file
                if [ -e $ECFLOWUI_UI_LOGFILE ] ; then
                    echo ""
                    echo "Last $UI_TAILNUM lines of user interaction log file:"
                    tail -${UI_TAILNUM} $ECFLOWUI_UI_LOGFILE
                fi
            fi
        fi
    fi



    # remove temporary directory
    if [ $(echo $ECFLOWUI_TMPDIR | grep -c "/ecflow_ui.") -ge 1 ] ; then
        rm -Rf $ECFLOWUI_TMPDIR
    fi

    exit $status
}



#-----------------------------------------------------------
# checkoption()
# Checks the command-line options
#-----------------------------------------------------------

checkoption() {

while [ "$1" != "" ]
do
	case "$1" in

		-log)
			ECFUI_SLOG=yes
			;;

		-slog)
			ECFUI_SLOG=yes
			;;

		-s)
			export ECFUI_SESSION_MANAGER=yes
			;;

		-ts)
			export ECFUI_TEMP_SESSION_HOST=$2
			export ECFUI_TEMP_SESSION_PORT=$3
			if [ "x$ECFUI_TEMP_SESSION_HOST" == x -o "x$ECFUI_TEMP_SESSION_PORT" == x ]
			then
				echo "Please supply a host and port:"
				echo "ecflow_ui -ts <host> <port>"
				exit 1
			fi
			echo "Starting a temporary session: host=$ECFUI_TEMP_SESSION_HOST, port=$ECFUI_TEMP_SESSION_PORT"
			shift 2
			;;

		-title)
			export ECFUI_TITLE=$2
            shift
			;;

		-h)
			ECFUI_HELP=yes
			;;

	esac
	shift
done
}



checkoption "$@"



#-----------------------------------------------------------
# Help message
#-----------------------------------------------------------

if [ "x$ECFUI_HELP" != x ]
then

    cat <<HEND
EcflowUI
  Command-line flags:
    -log              : write log messages to standard output
    -s                : start via the session manager
    -ts <host> <port> : start a temporary session viewing the given server
    -h                : print this help message
HEND

    exit 0
fi


#-----------------------------------------------------------
# usage log
#-----------------------------------------------------------

set +e  # failing to write to the log file should not cause a fatal error
if [ $ECFLOWUI_USAGE_LOG != x ]
then
	# checks on file existence and size
	if [ -f $ECFLOWUI_USAGE_LOG ]  # log file exists?
	then
		if [ ! -s $ECFLOWUI_USAGE_LOG ]  # file is empty? - write the header line
		then
			echo "date,time,version,user,host,site" >> $ECFLOWUI_USAGE_LOG
		fi

		echo "`date -u '+%Y.%m.%d,%R'`,$ECFLOWUI_VERSION,$USER,`hostname`,$ECFLOWUI_SITE_TAG" >> $ECFLOWUI_USAGE_LOG
	else
		echo "Log file $ECFLOWUI_USAGE_LOG does not exist."
	fi
fi
set -e



#Define tmp root dir
TMPDIR_ROOT=${TMPDIR:=/tmp}

# check that TMPDIR_ROOT actually exists - we can't run without it
if [ ! -d $TMPDIR_ROOT ]
then
    echo ""
    echo "  Temporary directory '$TMPDIR_ROOT' does not exist"
    echo "  ecFlowUI needs this in order to run. Check that environment"
    echo "  variable \$TMPDIR is set to a valid directory and try again."
    exit 1
fi

#Define and create tmp dir
export ECFLOWUI_TMPDIR=${TMPDIR_ROOT}/ecflow_ui.$$.$LOGNAME
mkdir -p $ECFLOWUI_TMPDIR

#Check if we could create it
if [ $? -ne 0 ]
then
    echo ""
    echo "  Temporary directory '$ECFLOWUI_TMPDIR' could not be created."
    echo "  ecFlowUI needs this in order to run. Check that environment"
    echo "  variable \$TMPDIR is set to a valid directory and try again."
    exit 1
fi


# Where to write the log file to
export ECFLOWUI_LOGFILE=$ECFLOWUI_TMPDIR/ecflowui_log_$$.$LOGNAME.txt

# Where to write the user interaction log file to
export ECFLOWUI_UI_LOGFILE=$ECFLOWUI_TMPDIR/ecflowui_uilog_$$.$LOGNAME.txt

#-----------------------------------------------------------
# Close tty and redirect stdout to a file?
#-----------------------------------------------------------

if [ x$ECFUI_SLOG != xyes ]
then
    exec  < /dev/null
    exec 5>&1                 # store for later
    exec 6>&2                 # store for later 
    exec 1> $ECFLOWUI_LOGFILE # (restored in cleanup())
    exec 2>&1                 # redirect stderr to stdout, (restored in cleanup())
    # note that it seems to be better to do
    #   exec 2>&1
    # rather than 
    #   exec 2> $ECFLOWUI_LOGFILE
    # because this way we get the stderr at the end rather than the start
    # due to the difference in flushing behaviours
fi



# =============================================================
# tmp directory cleaned automatically at end or at error.
# on new platforms check that these signals are valid:

ECFLOWUI_SIGLIST="HUP INT QUIT TERM XCPU  XFSZ"
#           1   2   3    15   30/24 31/25

trap 'cleanup "EXIT" $LINENO' EXIT
trap 'cleanup "SIGNAL trap" $LINENO' $ECFLOWUI_SIGLIST

#Figure out the directory of the exe
EXE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"


# note when we started it up
ECFLOWUI_STARTTIME=$(date)


#-----------------------------------------------------------
# Run the executable
#-----------------------------------------------------------

exe=${EXE_DIR}/ecflow_ui.x


#-----------------------------------------------------------
# Backtrace report?
#-----------------------------------------------------------

if [ $ECFLOWUI_BT != "no" ]
then
    catchsegv $exe
else
    ${exe}
fi

