#!/bin/bash

#============================================================================
# Copyright 2009-2020 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.17.1
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$ECFLOWUI_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)
            ECFLOWUI_SLOG=yes
            ;;

        -slog)
            ECFLOWUI_SLOG=yes
            ;;

        #Used by the exe
        -title)
            export ECFLOWUI_TITLE=$2
            shift
            ;;

        #Specify the location of the config dir. It is used for ui testing only.
        #We do not expose it in the usage() print out!!
        -confd)
            export ECFLOWUI_CONFIG_DIR=$2
            if [[ $ECFLOWUI_CONFIG_DIR  != /* ]] ; then
                echo "Please specify an absolute path for flag -confd!"
                exit 1
            fi
            echo "Starting logviewer with user specified config dir: ${ECFLOWUI_CONFIG_DIR}"
            shift
            ;;

        -h)
            ECFLOWUI_HELP=yes
            ;;
        *)
            ECFLOWUI_INPUT_FILE=$1
            shift
            ;;

    esac
    shift


done
}

print_usage() {

cat <<HEND
Usage:
ecflow_ui_log [-log -h logfile]

Command-line flags:
-log              : write log messages to standard output
-h                : print this help message
HEND
}

checkoption "$@"



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

if [ "x$ECFLOWUI_HELP" != x ]
then
    print_usage
    exit 0
fi

#-----------------------------------------------------------
# input file
#-----------------------------------------------------------

if [[ x"$ECFLOWUI_INPUT_FILE" != x && ! -f $ECFLOWUI_INPUT_FILE ]] ; then

    echo "The specified logfile does not exist!"
    print_usage
    exit 1
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_log.$$.$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

#---------------------------------------------------------------
# Create socket dir for local domain socket base communication
#---------------------------------------------------------------

#export ECFLOWUI_SOCKETDIR=$ECFLOWUI_TMPDIR/sockets
#mkdir -p $ECFLOWUI_SOCKETDIR

#---------------------------------------------------------------
# Remove lock files created more than 3 s ago (see ECFLOW-980)
#---------------------------------------------------------------

confDir=${ECFLOWUI_CONFIG_DIR:=${HOME}/.ecflow_ui}
#We are extra careful an delete the files in a loop instead of using exec for find
for fn in $(find $confDir -type f -cmin +0.05 -name *.lock) ; do
    if [[ $fn == *.lock ]] ; then
        echo "Remove lock file: ${fn}"
        rm -f $fn
    fi
done

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

if [ x$ECFLOWUI_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_log.x

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

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

