#!/bin/zsh
#
#
# \author mdejong
#
#--------------------------------------------------------------------------------------
#
#                   Utility script for zsh library functions.
#
#--------------------------------------------------------------------------------------

version=1.0


typeset -i DEBUG=0                    # debug level
export     DEBUG

typeset -i TIMER=0                    # timer
export     TIMER

export DEFAULT_OPTION=-               # default option 


# Wild card for any valid run number to be used as ${~ANY_RUN_NUMBER}.

export ANY_RUN_NUMBER="[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"

export ARCA_DETECTOR_ID=00000014      # ARCA detector identifier
export ORCA_DETECTOR_ID=00000029      # ORCA detector identifier
export PI=3.14159265359


#
# debug messages
#
function fatal()   { 
    echo `date` FATAL   $* 
    exit 1
} 
function error()   { if (( $DEBUG >= 0 )); then echo `date` ERROR   $* ; fi }
function notice()  { if (( $DEBUG >= 1 )); then echo `date` NOTICE  $* ; fi }
function status()  { if (( $DEBUG >= 2 )); then echo `date` STATUS  $* ; fi }
function warning() { if (( $DEBUG >= 2 )); then echo `date` WARNING $* ; fi }
function debug()   { if (( $DEBUG >= 3 )); then echo `date` DEBUG   $* ; fi }


#
# Method to check for usage of script.
#
# \param  1-N     list of command line options
# \return         0 for option -h; else 1
#
function do_usage()
{
    for variable in $*; do
	if [[ "$variable" == "-h" || "$variable" == "-h!" ]]; then
	    return 0
	fi
    done

    return 1
}


#
# Method to print usage of script and exit.
#
# \param  1-N     usage
#
function usage()
{
    echo "$*"
    exit
}


#
# check exit code
# The last parameter refers to the exit code.
#
# \param  1-N     message
# \param  N       exit code
#
function check_exit_code()
{
    if (( $argv[-1] )); then
	error  $*
	exit   $argv[-1]
    else
	notice $*
    fi
}


#
# test quality
#
# \param  1       first  value
# \param  2       second value
#
function test_equality
{
    if [[ "$1" != "$2" ]]; then
	fatal "<$1> != <$2>"
    else
	debug "<$1> == <$2>"
    fi
}


#
# check exit code alias
#
alias CHECK_EXIT_CODE="check_exit_code \$0 \$* \$?"


#
# Method to check if inside a conda env.
#
function has_conda()
{
    if [ -n "${CONDA_PREFIX+1}" ]; then
        return 0
    else
        return 1
    fi
}


#
# Method to check for CC Lyon.
#
# \return         1 for CC Lyon; else 0
#
function is_CCLyon()
{
    if [[ -n "${HOST}" && "${HOST:0:2}" =  "cc" ]]; then
	return 0
    else
	return 1
    fi
}


#
# Method to define variable.
#
# \param  1       variable
#
function define_variable()
{
    local variable=$1

    eval export $variable
}


#
# Method to set variable.
# Note that a value equal to $DEFAULT_OPTION will not modify the variable.
#
# \param  1       variable
# \param  2-N     value(s)
#
function set_variable()
{
    local variable=$1
    shift

    if [[ "$*" != "$DEFAULT_OPTION" ]]; then
	eval export $variable=\"$\*\"
    fi
}


#
# Method to unset variable.
#
# \param  1       variable
#
function unset_variable()
{
    local variable=$1

    eval unset $variable
}


#
# Method to print variables.
#
# \param  1-N     list of variables
#
function print_variable()
{
    for variable in $*; do
	eval value=\${$variable}
	printf "%-20s = %s\n" ${variable} "${value}"
    done
}


#
# Method to check validity of variables.
#
# \param  1-N     list of variables
#
function check_variable()
{
    for variable in $*; do
	eval value=$+${variable}
	if (( ${value} == 0 )); then
	    fatal "Variable ${variable} not defined."
	fi
    done
}


#
# Method to count directory in ':' separated path list.
#
# \param  1       path list
# \param  2       directory
#
function count_directory()
{
    eval key=\${$1}
    
    echo -n $key | tr ":" "\n" | grep "^\\${2}$" | wc -w
}


#
# Method to remove directory from ':' separated path list.
#
# \param  1       path list
# \param  2       directory
#
function remove_directory()
{
    eval key=\${$1}
    eval value=$2

    if [[ -n "$key" && -n "$value" ]]; then
	export $1=`eval echo $key | tr ":" "\n" | grep -v "^\\\\${value}$" | tr "\n" ":" | sed 's/:\$//'`
    fi
}


#
# Method to remove variable from ':' separated path list.
#
# \param   1      path list
# \param   2      variable
#
function remove_variable()
{
    eval key=\${$1}
    eval value=\${$2}

    if [[ -n "$key" && -n "$value" ]]; then
	remove_directory $1 $value
    fi
}


#
# Method to insert directory into ':' separated path list.
#
# \param   1      path list
# \param   2      directory
#
function insert_directory()
{
    eval key=\${$1}

    if [[ -z "$key" ]]; then
	export $1=$2
    elif (( `eval echo -n $key | tr ":" "\n" | grep "^\\\\${2}$" | wc -w` == 0 )); then
	export $1=$2:${key}
    fi
}


#
# Method to check process path.
#
# \param   1-N    list of process names
#
function check_process()
{
    for process in $*; do

	local bin=`which $process 2>& /dev/null`
	debug "Check process ${process}=${bin}"

	if [ -z "${bin}" ]; then
	    fatal "Process ${process} not found."
	fi
    done
}


#
# Method to check file access.
#
# \param   1-N    list of files
#
function check_input_file()
{
    if (( $# == 0 )); then
	fatal "No input file."
    fi
    
    for file in `echo $*`; do

	debug "Check input file: ${file}"

	if   [[ ! -f ${file} ]]; then
	    fatal "File ${file} not found."
	elif [[ ! -r ${file} ]]; then
	    fatal "File ${file} not readable."
	fi
    done
}


#
# Method to check file access.
#
# \param   1-N    list of files
#
function check_output_file()
{
    for file in `echo $*`; do

	debug "Check output file: ${file}"

	if [[ -f ${file} ]]; then
	    fatal "File ${file} already exists."
	fi
    done
}


#
# Method to reuse file.
# Note that this method may require user interaction.
#
# \param   1      file name
# \return         1 when absent; else 0
#
function reuse_file()
{
    if   [[ -f $1 ]]; then
        rm -i $1
    fi

    if   [[ ! -f $1 ]]; then    
	return 1
    else
	return 0
    fi
}


#
# Get process identifier.
#
# \param          [hostname]
# \param          process name
# \return         PID
#
function get_pid()
{
    if   (( $# == 1 )); then
	exec ps h -o "%p" -C $1 
    elif (( $# == 2 )); then
	exec ssh $1 "ps h -o "%p" -C $2"
    fi
}


#
# Method to start timer
#
function timer_start()
{
    TIMER=$(date +%s)
}


#
# Method to stop timer
#
function timer_stop()
{
    TIMER=$(($(date +%s) - $TIMER))
}


#
# Method to print timer
#
function timer_print()
{
    echo "Elapsed time $TIMER s."
}
