#!/bin/sh
# PURPOSE:	write a breakpoint for calSelector into calsel_breakpoints QC1 database table
# AUTHOR:	Burkhard Wolff, ESO-DMO
# VERSION:	1.0 -- September 2014
#		1.1 -- identify PRO.CATGs belonging to RAW_TYPEs and ingest PRO.CATGs in database (2016-03-16)
#		1.2 -- identify DO.CLASS  belonging to RAW_TYPEs and ingest DO.CLASS as additional column (2023-09-14)
# CONFIG:	none (uses config.dfoMonitor for XTERM_GEOM)
#		requires calSelector OCA rules in $DFO_CONFIG_DIR/CALSELECTOR
# TOOLS CALLED:	qc1Ingest
# OUTPUT:	list of qc1Ingest calls in $DFO_LST_DIR/CALSEL_BP/list_ingest_breakpoints.txt
# COMMENTS: 	none
# ===================================================================================
TOOL_VERSION="1.2"

# ===================================================================================
# 0. Initialization
# 0.1 Check environment
# ===================================================================================

CHECK=`printenv | grep DFO`

if [ "Q$CHECK" = "Q" ]
then
        echo "*** ERROR: DFO variables not defined. Check ~/.dfosrc and restart."
        exit -1
fi

# =========================================================================
# 0.2 get options
# =========================================================================

while getopts hv OPTION
do
        case "$OPTION" in
         v ) echo "$TOOL_VERSION"
             exit 0 ;;
         h ) cat $DFO_DOC_DIR/writeBreakpoint.h | more
             exit 0 ;;
        esac
done

# =========================================================================
# 0.3 Initialize some parameters
# =========================================================================

# use config.dfoMonitor to read XTERM_GEOM
CONFIG=$DFO_CONFIG_DIR/config.dfoMonitor
if [ ! -s $CONFIG ]
then
        echo "*** ERROR: No configuration file $CONFIG found. Check and re-start."
        exit -1
fi

XTERM_GEOM=`grep "^XTERM_GEOM"		$CONFIG | awk '{print $2}'`
if [ Q$XTERM_GEOM = Q ]
then
	XTERM_GEOM="125x25+1600+900"
fi

if [ Q$DFO_EDITOR = Q ]
then
	echo "***ERROR: you need to define \$DFO_EDITOR (e.g. vi, vim, emacs) in .dfosrc, then source and start again. Exit."
	exit -1
fi

FILE_EDITOR=`eval "echo $DFO_EDITOR "`

# check for directory where qc1Ingest calls are saved
BP_LST_DIR=$DFO_LST_DIR/CALSEL_BP
if [ ! -d $BP_LST_DIR ]
then
	mkdir $BP_LST_DIR
fi

# find latest calSelector OCA rules
if [ ! -s $DFO_CONFIG_DIR/CALSELECTOR/config.createCalibMap.calsel ]
then
	echo "***ERROR: config file \$DFO_CONFIG_DIR/CALSELECTOR/config.createCalibMap.calsel not found."
	echo "          Proper calSelector OCA rules are needed for functioning of this tool. Please check."
	echo "          Exit."
	exit -1
fi
START_DATE=`grep ^START_DATE ${DFO_CONFIG_DIR}/CALSELECTOR/config.createCalibMap.calsel | awk '{print $2}' | sort -u | tail -1`
OCA_CONF=${DFO_CONFIG_DIR}/CALSELECTOR/${START_DATE}/${DFO_INSTRUMENT}_raw2master.${START_DATE}.RLS
if [ ! -s $OCA_CONF ]
then
	echo "***ERROR: expected calSelector rules file "
	echo "            \$DFO_CONFIG_DIR/CALSELECTOR/${START_DATE}/${DFO_INSTRUMENT}_raw2master.${START_DATE}.RLS"
	echo "          could not be found."
	echo "          Proper calSelector OCA rules are needed for functioning of this tool. Please check."
	echo "          Exit."
	exit -1
fi

# check for operational OCA classification
OCA_CLASS=${DFO_CONFIG_DIR}/OCA/${DFO_INSTRUMENT}_classification.h
if [ ! -s $OCA_CLASS ] 
then
	echo "***ERROR: expected OCA classification file "
	echo "             $OCA_CLASS"
	echo "          could not be found."
	echo "          Exit."
	exit -f
fi

rm -rf $TMP_DIR/bp_comment $TMP_DIR/bp_rawtypes

# =========================================================================
# 0.4 Function to find all PRO.CATGs per RAW_TYPE
# =========================================================================

getPRO_CATG(){
	RT=$1
	rm -rf $TMP_DIR/bp_procatgs
	ACTION=`cat $OCA_CONF | grep select | grep execute | grep "\"${RT}\"" | sed "s/^.*execute(//" | sed "s/).*//"`
	cat $OCA_CONF |\
	awk '{if ( $1 == "action" && $2 == ACTION ) {BRA=1}; if ( $1 == "action" && $2 != ACTION ) {BRA=0}; if (BRA == 1 && $1 == "product") {print $0} }' ACTION=$ACTION | sed "s/^.*PRO.CATG//" | sed "s/=//g" | sed "s/\"/ /g" | awk '{print $1}' >> $TMP_DIR/bp_procatgs
}

# =========================================================================
# 0.5 Function to find all DO.CLASS per RAW_TYPE
# =========================================================================

getDO_CLASS(){
	RT=$1
	rm -rf $TMP_DIR/bp_doclass
	cat $OCA_CLASS | sed "s/=/ /g" | sed "s/\"/ /g" |\
		awk '{if ( $1 == "RAW.TYPE" && $2 == TYPE) {BRA=1}; if ( BRA == 1 && $1 == "DO.CLASS") {print $2; BRA=0}}' TYPE=$RT | sort -u > $TMP_DIR/bp_doclass
}

# =========================================================================
# 1.0 dialog
# =========================================================================

echo "*** writeBreakpoint ***"
echo "Write a breakpoint for calSelector into calsel_breakpoints QC1 database table"

echo
echo "1. Enter all information for defining a calSelector breakpoint for ${DFO_INSTRUMENT}:"
echo "- Exact MJD-OBS of breakpoint (respecting the \$DFO_OFFSET convention; if in doubt, use the 'MJD_OBS' column of a data report):"
read MJD_OBS

if [ Q$MJD_OBS = Q ]
then
	echo "***ERROR: you must provide MJD_OBS for the breakpoint. Exit."
	exit -1
fi

echo "- Comment/reason for breakpoint (one line, max. 80 characters):"
xterm -T "Comment/reason for breakpoint (one line, max. 80 characters)" -geom $XTERM_GEOM -e "$FILE_EDITOR $TMP_DIR/bp_comment"

# use number of words to check for empty comment
# emacs does not add <END-OF-LINE> character, wc -l gives then 0
CHECK=`wc -w $TMP_DIR/bp_comment | awk '{print $1}'`
if [ $CHECK -eq 0 ]
then
	echo "*** ERROR: empty comment. Exit."
	exit
fi

# check for additional lines
CHECK=`wc -l $TMP_DIR/bp_comment | awk '{print $1}'`
if [ $CHECK -gt 1 ]
then
	echo "*** WARNING: more than one line entered, additional lines will be truncated"
fi
COMMENT=`cat $TMP_DIR/bp_comment | sed "2,$ d"`

# check for additional characters
CHECK=`echo $COMMENT | wc -c`
if [ $CHECK -gt 81 ]
then
	echo "*** WARNING: more than 80 characters entered, additional characters will be truncated" 
	COMMENT=`echo $COMMENT | cut -c1-80`
fi

echo "- Is this breakpoint applicable to ALL raw types (Y/N)? (Y)"
read YES_NO
if [ "Q$YES_NO" != "QN" ] 
then
	echo "S ANY" >> $TMP_DIR/bp_rawtypes
else
	echo "- We will use the latest calSelector rule set"
	echo "    $OCA_CONF "
	echo "  for determining RAW_TYPEs and PRO.CATGs."
	echo "- Do you want to use a different calSelector OCA rule set (Y/N) ? (N)"
	read YES_NO
	if [ "Q$YES_NO" = "QY" ]
	then
		echo "- Please enter full path to the OCA rule set:"
		read OCA_CONF
		OCA_CONF=`eval "echo $OCA_CONF "`
		if [ ! -s $OCA_CONF ]
		then
			echo "*** ERROR: the OCA rule set"
			echo "             $OCA_CONF "
			echo "           Does not exist. Please check and restart. Exit."
			exit -1
		fi
	fi
	cat $OCA_CONF | sed "s/ *== */==/g" | sed "s/(//g" | sed "s/)//g" | \
	awk '{if ( $1 == "if" ) {for (i=1; i<=NF; i=i+1) {if ( $i == "DPR.CATG==\"CALIB\"" ) {cal = 1} }} if ( cal == 1 ) {if ( $1 == "RAW.TYPE") {print $0; cal=0}} if ( $1 == "}" ) {cal=0}}' | \
	sed "s/ //g" | sed "s/RAW.TYPE=//" | sed "s/\"//g" | sed "s/;//g" | sort -u >> $TMP_DIR/bp_rawtypes
	echo "- Mark raw types with leading 'S<blank>' and then exit"
	xterm -T "Mark raw types with leading 'S<blank>'" -geom $XTERM_GEOM -e "$FILE_EDITOR $TMP_DIR/bp_rawtypes"
fi

CHECK=`cat $TMP_DIR/bp_rawtypes | grep "^S " | wc -l`
if [ $CHECK -lt 1 ]
then
	echo "*** ERROR: no raw type selected. Exit."
	exit
fi

# =========================================================================
# 2.0 Check and insert
# 2.1 Check
# =========================================================================

# calculate civil date with QC date change at 21.00 UT
MJD_DATE=`echo $MJD_OBS | awk '{printf("%f",$1-21/24)}'`
CIVIL_DATE=`qcdate $MJD_DATE`

echo
echo "2. Verify parameters of calSelector breakpoint(s):"
echo "- instrument: ${DFO_INSTRUMENT}"
echo "- DP instrument name: ${DFO_FILE_NAME}"
echo "- mjd_obs: ${MJD_OBS}"
echo "- civil_date: ${CIVIL_DATE}"
echo "- comment: ${COMMENT}"
echo "- for raw types:"
cat $TMP_DIR/bp_rawtypes | grep "^S " | awk '{print $2}'
echo
echo "OK (Y/N)? (N)"
read YES_NO
if [ "Q$YES_NO" != "QY" ]
then
	echo "Exit. Breakpoint(s) not inserted."
	exit
fi

# =========================================================================
# 2.2 Insert
# =========================================================================

echo
echo "3. Breakpoints will be ingested now. Check output for errors."

for RAW_TYPE in `cat $TMP_DIR/bp_rawtypes | grep "^S " | awk '{print $2}'`
do
	if [ "$RAW_TYPE" = "ANY" ]
	then
		echo ANY > $TMP_DIR/bp_procatgs
		echo ANY > $TMP_DIR/bp_doclass
	else
		getPRO_CATG $RAW_TYPE
		getDO_CLASS $RAW_TYPE
	fi
	for CATG in `cat $TMP_DIR/bp_procatgs`
	do
		for CLASS in `cat $TMP_DIR/bp_doclass`
		do
			COMMAND=`eval "echo \"qc1Ingest -table calsel_breakpoints -raw_type ${RAW_TYPE} -pro_catg ${CATG} -do_class ${CLASS} \
			-instrument ${DFO_INSTRUMENT} -dp_instrument ${DFO_FILE_NAME} -plot_value 1 -mjd_obs ${MJD_OBS} \
			-civil_date ${CIVIL_DATE} -comment '${COMMENT}' \" "`
			#echo ${COMMAND}
			eval "${COMMAND}"
			echo $COMMAND >> $BP_LST_DIR/list_ingest_breakpoints.txt
		done
	done
done

echo "Ingestion commands added to $BP_LST_DIR/list_ingest_breakpoints.txt"
echo "Done."

