#!/bin/bash

#########################################
# Name: qsee
#
# Summary: generate xFOCE quick look plots
#
# Description: 
# Uses xpres to generate CSV data files
# then uses qplot to plot them.
#
# The easiest way to use qsee is to create
# config files for qsee, xpres and qplot; each
# specifying the appropriate command line options
# (one option/value pair per line).
# The qsee config file reference the 
# qplot configurations using the -p option.
#
# Then, invoke qsee like this
#
#    qsee < my.conf
# or
#    cat my.conf | qsee
#
# Override config file options by passing them 
# on the qsee command line:
#
#    qsee -l 24 < my.conf
#
# Author: kheadley
#
# Copyright MBARI 2014
#
#########################################

#########################################
# Script configuration defaults
# casual users should not need to change
# anything below this section
#########################################

# -x xpres_cfg
XPRES_CFG="qs-xpres.conf"

# -d arch_dir
ARCH_DIR=""
if [ -d "${XF_HOME}" ]
then
	ARCH_DIR="${XF_HOME}"/arch	
else
	ARCH_DIR="."	
fi

# -o output directory
QSOUT_DIR="qsout"

# -V verbose
VERBOSE="FALSE"
XPRES_CMD="xpres"
QPLOT_CMD="qplot"
QSEE_LOG="qsee.log"

#################################
# Script variable initialization
#################################
# -s source,stream[,n]
declare -a SOURCES
# -p qplot_cfg
declare -a PLOTS
XPRES_BASE_OPTS=""
XPRES_OPTS=""
unset BTIME
unset ETIME

#################################
# Function Definitions
#################################
#################################
# name: sigTrap
# description: signal trap callback
# will interrupt 
# args: none
#################################
sigTrap(){
    exit 0;
}

#################################
# name: printUsage
# description: print use message
# args: none
#################################
printUsage(){
    echo
    echo "# batch process quick look plots"
    echo ""
    echo "usage: `basename $0` [options] plots..."
    echo "-x <file>        : xpres config    [$XPRES_CFG]"
    echo "-d <arch>        : arch path       [$ARCH_DIR]"
    echo "-B <ets>         : begin time"
    echo "-E <ets>         : end time"
    echo "-b <iso>         : begin time (iso)"
    echo "-e <iso>         : end time (iso)"
    echo "-l <n>           : last n hours"
    echo "-s <src,str[,n]> : data source "
    echo "                    - src: source ID"
    echo "                    - str: stream ID [recommended] "
    echo "                    -   n: modulus   [optional]"
    echo "-p <file>        : plot config "
    echo "-V               : verbose output  [$VERBOSE]"
    echo "-h               : help "
    echo ""
    echo "The easiest way to use qsee is to create"
    echo "config files for qsee, xpres and qplot; each"
    echo "specifying the appropriate command line options"
    echo "(one option/value pair per line)."
    echo "The qsee config file reference the "
    echo "qplot configurations using the -p option."
    echo ""
    echo "Then, just invoke qsee like this"
    echo "    qsee < my.conf"
    echo ""
    echo " Override config file options by passing them "
    echo " on the command line:"
    echo "    qsee -l 24 < my.conf"
    echo
}

########################################
# name: vout
# description: print verbose message to stderr
# args:
#     msg: message
########################################
vout(){
    if [ "$VERBOSE" == "TRUE" ]
    then
	echo "$1" >&2
    fi
}

########################################
# name: imsg
# description: echos with indent
# args:
#     msg: message
#  indent: indent level
########################################
imsg(){
  OIFS=$IFS
  IFS=""
  msg_pad="                                        "
  let "msg_indent=${1}"
  shift
  all="${@}"
  printf "%s%s\n" ${msg_pad:0:${msg_indent}} ${all}
  IFS=$OIFS
}

########################################
# name: msg
# description: echos with default indent
# args:
#     msg: message
########################################
msg(){
 imsg $MSG_INDENT "${*}"
}

########################################
# name: exitError
# description: print use message to stderr
# args:
#     msg:        error message
#     returnCode: exit status to return
########################################
exitError(){
    echo >&2
    echo "$1" >&2
    echo >&2
    exit $2
}

########################################
# name: processCmdLine
# description: do command line processsing
# args:
#     args:       positional paramters
#     returnCode: none
########################################
processCmdLine(){
	OPTIND=1
    vout "`basename $0` all args[$*]"
	while getopts b:B:d:e:E:l:s:p:x:hV Option
	do
		vout "`basename $0` Processing option - $Option[$OPTARG]"
		case $Option in
			b ) BTIME="-b $OPTARG"
			;;
			e ) ETIME="-e $OPTARG"
			;;
			B ) TEST=$OPTARG
				if [ "$TEST" -lt 0 ]
				then
					exitError "invalid start time [$TEST]"
				fi
				BTIME="-B $OPTARG"
			;;
			E ) TEST=$OPTARG
				if [ "$TEST" -lt 0 ]
				then
					exitError "invalid end time [$TEST]"
				fi
				ETIME="-E $OPTARG"
			;;
			l ) TEST=$OPTARG
				if [ "$TEST" -lt 1 ]
				then
					exitError "invalid end time [$TEST]"
				fi
				TNOW=`date +%s`
				let "TB=$TNOW-$TEST*3600"
				BTIME="-B $TB"
				
			;;
			d ) ARCH_DIR=$OPTARG
			;;
			s ) SOURCES[${#SOURCES[*]}]=$OPTARG
			;;
			p ) PLOTS[${#PLOTS[*]}]=$OPTARG
			;;
			x ) XPRES_CFG=$OPTARG
			;;
			V ) VERBOSE="TRUE"
			;;
			h)printUsage
			  exit 0
			;;
			*) exit 0 # getopts outputs error message
			;;
		esac
	done
}
##########################
# Script main entry point
##########################


# Argument processing
# Accepts arguments from command line 
# or pipe/file redirect
# Comand line settings override config
# file settings

if [ -t 0 ]
then
	if [ "$#" -eq 0 ];then
		printUsage
		exit -1
	else
		processCmdLine $*
		
		let "i=$OPTIND-1"
		while [ "${i}" -gt 0  ]
		do
			shift
			let "i-=1"
		done
	fi
else	
	# save command line args
	declare -a cline_args
	let "i=1"
	while [ "$i" -le "$#" ]
	do
		cline_args[$i]="${@:$i:1}"
		let "i+=1"
	done
	
	# process config file 
  	declare -a arg_array
	let "z=0"
	while read line ; do
		IFS=" " read opt val <<< $line
		if [ "${opt}" ] && [[ $opt != \#* ]]
		then
		    vout "opt $opt $z"
			arg_array[$z]=${opt}
			let "z+=1"
			if [ "${val}" ]
			then
				vout "val $val $z"
				arg_array[$z]=${val}
				let "z+=1"
			fi
		else 
			vout "skipping line $line"
		fi
	done
	# set default delimiter to 
	# newline for parsing/setting
	# positional parameters
	# [must restore after processing]
	IFSO=$IFS
	IFS=`echo` 
	set - ${arg_array[*]}

	# apply config file settings
	processCmdLine ${arg_array[*]}

	# apply command line settings
	# (override config file options)
	set - ${cline_args[*]}	
	processCmdLine ${cline_args[*]}

	# restore default delimiter
	IFS=$IFSO

	#let "i=$OPTIND-1"
	#while [ "${i}" -gt 0  ]
	#do
	#shift
	#let "i-=1"
	#done
		
fi


# call sigTrap on INT,TERM or EXIT
# trap sigTrap INT TERM EXIT

# reset trapped signals
# trap - INT TERM EXIT


vout "BTIME   : ${BTIME}"
vout "ETIME   : ${ETIME}"
vout "ARCH    : ${ARCH_DIR}"
vout "XPRES   : ${XPRES_CFG}"
vout "SOURCES : ${SOURCES[*]}"
vout "PLOTS   : ${PLOTS[*]}"

if [ "${#SOURCES}" -le 0 ]
then
	exitError "No sources specified" -1
fi

# validate args...
if [ -f "${QSOUT_DIR}" ]
then
	exitError "invalid output directory [${QSOUT_DIR}]" -1
fi

# create output directory
if  [ ! -e "${QSOUT_DIR}" ]
then
	mkdir ${QSOUT_DIR}
fi

XPRES_OPTS=""

# set time format args...
if [ "${BTIME}" ]
then
	XPRES_OPTS="${XPRES_OPTS} ${BTIME}"
fi
if [ "${ETIME}" ]
then
	XPRES_OPTS="${XPRES_OPTS} ${ETIME}"
fi

# Save common options
XPRES_BASE_OPTS=${XPRES_OPTS}

# Generate data files
let "i=0"
while [ "${i}" -lt "${#SOURCES[*]}" ]
do
	IFSO=$IFS
	IFS="," 
	read src str mod out <<< "${SOURCES[$i]}"
	IFS=$IFSO
	
	# src is required
	if [ "${src}" ]
	then
		
		XPRES_OPTS="${XPRES_OPTS} -s ${src}"
		# optional stream
		if [ "${str}" ]
		then
			XPRES_OPTS="${XPRES_OPTS} -t ${str}"
		fi
		# options decimation modulus
		if [ "${mod}" ]
		then
			XPRES_OPTS="${XPRES_OPTS} -n ${mod}"
		fi
		
		# name output file
		ofile="${QSOUT_DIR}/${src}-${str}.dat"

		# generate data file
		vout "${XPRES_CMD} ${XPRES_OPTS} < ${XPRES_CFG} > ${ofile}"
		${XPRES_CMD} ${XPRES_OPTS} < ${XPRES_CFG} > ${ofile} 2> ${QSEE_LOG}

		# reset vars
		XPRES_OPTS="${XPRES_BASE_OPTS}"
		unset OFILE
		unset src
		unset str
		unset mod
	fi
	let "i+=1"
done

# Generate plot files
let "i=0"
while [ "${i}" -lt "${#PLOTS[*]}" ]
do
	vout "plotting using config [${PLOTS[$i]}]"
	${QPLOT_CMD} < ${PLOTS[$i]} &>> ${QSEE_LOG}
	let "i+=1"
done
