#!/bin/sh
# PURPOSE:      interface between ABs and pipelines
# AUTHOR:       Reinhard Hanuschik / ESO April 2004
# VERSION:      0.8 -- April 2004
#               ...
#		1.0 -- supports dfosLog; released (2004-08-12)
#		1.1 -- TMP_DIR-->JTMP_DIR; no removal of WORK_AREA if RENAME_SHIFT!=YES (2004-09-07)
#		1.2 -- Two MONITOR_PLUGINS: start/end (2004-09-14)
#		1.2.1- startRBS enabled (2004-09-15)
#		1.2.2- esorex called with explicit outputdir (2004-09-16)
#		1.3 -- product checks for RBS refined; writes status line into AB; moves PAF files (2004-09-17)
#		1.3.1- bug with success check for RBS fixed (2004-09-21)
#		1.3.2- bug with PARAM = NONE fixed (2004-09-23)
#		1.4 -- have PAF_MOVE for better treatment of paf files (2004-09-24)
#		1.4.1- another bug with PAF_MOVE fixed (2004-09-30)
#		1.4.2- use EXIT_CODE of esorex to suppress products of unsuccessful recipe runs (2005-01-19) 
#		1.4.3- verifies existance of $WORK_AREA (2005-02-17)
#		1.4.4- OTH included as supported DRS_TYPE (2005-04-04)
#		1.4.5- ambiguous orig_filenames supported (2005-04-14)
#		1.4.6- calculate AB execution time (2005-05-10)
#		1.4.7- fix bug for DRS=RBS; stop RZ/RX support (2005-05-12)
#		1.4.8- small changes to support CONDOR (2005-06-07)
#		1.4.9- small changes related to RENAME_SHIFT (2005-10-13)
#		1.4.10- small changes to align with createAB v2.0 (2006-02-16)
#		1.5 -- compatible with createAB v2.0 (2006-03-03)
#		1.6 -- MEF-enabled: includes new option -e (to support CONDOR recipe calls per detector); pgi_PIPEFILE obsolete; TOOL_LOGGING obsolete, dfosLog suspended (2006-03-21)
#		1.6.1- bug fixed for DRS_TYPE=RBS (2006-06-07)
#		1.6.2- supported DRS_TYPEs hard-coded (2006-09-20)
#		1.6.3- USE_AB_DRS_TYPE added; PAF_MOVE removed (2007-04-26)
#		1.6.4- startRBS -f added (2007-07-26)
#               1.7 -- download RAWFILEs plus REAL MCALIBs and MASSOCS from CDB if do not exist locally [JDP] (2007-11-15)
#		1.7.1- bug fixed with handling of AB w/o RAWFILEs (2007-11-29)
#		1.7.2- improved raw_type scan in line 644 (2008-01-25)
#		1.7.3- message in line 468 changed (2008-03-05)
#		1.7.4- moved RAW and CALIB download blocks so that not downloaded for RECIPE=NONE; DEBUG mode [JDP] (2008-03-06)
#		1.7.5- RBS support stopped; improved error handling with ngasClient errors (2008-07-29)
#		1.7.6- improved error handling for data downloads (2008-09-25)
#		1.7.7- implemented ERROR_PLUGIN [JDP] (2008-11-03)
#               1.8 -- improved DET_SPLIT handling (AB_STATUS, TEXEC) and handling of ABScheduler (2009-01-29) [WHu]
#		1.8.1- feature with DONE files fixed (as a temporary solution) (2009-02-04)
#		1.8.2- if configured (ACCEPT_FZ), accept fits.fz files (2009-10-23)
#		1.8.3- bug fixed with fits.fz.fz files (2010-01-20)
#		1.9 -- MASSOC download stopped (unless MASSOC_DOWN=YES); PIPE_NAME configurable (2010-02-02)
#		1.9.1- added line :99 as required by ScientificLinux 5.3 (2010-07-30)
#		1.10 - modified esorex call to support optional detmon pipeline config file; optional key ABS_SUPPORT (2011-01-21)
#		1.10.1- $DFO_MON_DIR/MCAL_DOWNLOAD (2011-05-30)
#		2.0 -- support AB tab files; includes upper limit for N_rawfiles; terminated: MASSOC_DOWN, USE_AB_DRS_TYPE, END_MONITOR_PLUGIN, START_MONITOR_PLUGIN  (2013-01-09)
#		2.0.1- bug fix related to AMODE=TECHNICAL or TEST (2013-01-15)
# 		2.1 -- ABS_SUPPORT terminated; FINAL_PLUGIN, MONO_CALL in RENAME_SHIFT (2013-01-24)
#		2.1.1- minor improvements in lines :552 and :940 (2013-06-12)
#		2.2 -- ACQUISITIONS included in CALIB mode (line :627) [BWo] (2013-07-31)
#		2.2.1- minor bug with notification mail fixed (2014-05-19) 
#		2.3 -- support for DRS_TYPE=INT added (2014-07-22)
#		2.4 -- support for DFOS and PHOENIX (2014-08-20)
#		2.5 -- download of rawfiles also for recipe=none, for RAWDISP; new optional config key DRS_FROM_AB and NO_CHECKSUM for PHOENIX (2015-08-31)
#		2.5.1- bug fix in Sect. 2.2: ngasClient called also for RAWDISP_SUPPORT=NO unless RECIPE=NONE (2015-10-21)
#		2.6 -- measure delay (processing time <-> arcfile timestamp), write into dfo table delay_time (2015-10-28)
#		2.6.1- two keys added for delay_time (2015-10-29)
#		2.6.2- support for DET decommissioned, PROCESSED_BY_AUTOD set correctly for DRS_TYPE=INT (2015-11-02)
#		2.6.3- limitation of delay_time to 1440 min; bug fix for getDelay (date --> date -u) (2015-11-03)
#		2.6.4- read from last rawfile in AB; read DELAY and DELIVERY (2015-11-09)
#		2.6.5- new optional key CHECK_SOF_EXIST for PHOENIX (2015-12-22)
# 		2.6.6- error messages upon mkdir suppressed (around :705) (2017-09-05)
#		2.6.7- pgi_PIPEFILE, PIPE_NAME, PIPE_HOME removed from code (2018-02-21)
# 		2.7 -- OPSHUB aware (TAB files to link to $DFS_PRODUCT, for -i $INSTR and -u $USER) (2018-08-02)
# 		2.7.1- minor improvement in ATAB handling around :406
#		2.7.2- adding PIPE_ID to AB_STATUS (2018-11-30)
#		2.7.3- no call of getDelay for PHOENIX (2019-02-04)
#		2.7.4- take first instance of START_TIME and last instance of END_TIME for TEXEC, around :1150 (2019-03-08)
#		2.7.5- exit getDelay if no RAWFILE (2019-04-04, BWo)
#		2.7.6- disabled and removed getDelay, obsolete with transition to DFOS-v2 (2021-04-26)
#
# PARAMETERS:   AB
# OUTPUT:       pipeline processing log 
# TOOLS CALLED:	ngasClient (mcalib file download)
# CONFIG FILE:  config.processAB; also: config.createAB; config.processQC for RAWDISP_SUPPORT
# COMMENTS:    	supported DRS (from createAB):
#		CPL - calling esorex (queue mode)
#		CON - CONDOR (batch queue system calling esorex)
#		INT - internal splitting, ABs in queue mode
# NOTES:	- Make sure that $WORK_AREA as defined in the config file exists!
#		- ACCEPT_FZ: if YES, files from the sof are downloaded only if neither .fits nor .fits.fz versions exist.
#		  Useful for .fz enabled pipelines. (.fz: tile-compressed file, e.g. for VIRCAM)
#		- detmon/general pipeline: see www.eso.org/~qc/docu/detmon/index.html for more.
#		- CALIB mode: includes CALIB, TECHNICAL, ACQUISITION
#		- supporting PHOENIX
# =====================================================================================================================================
TOOL_VERSION="2.7.6"
TOOL_NAME="processAB"
MAXN_RAW=10			# maximum number of raw files accepted for automatic incremental mode processing, unless configured in MAXN_RAW, or run with -F

# =========================================================================
# 0. Initialize
# 0.1 read params
# =========================================================================

if [ $# = 0 ]
then
	cat $DFO_DOC_DIR/processAB.h | more
	exit 0 
fi

PROCESSAB_DEBUG="N"
FORCE_EXEC="N"

# if DRS_TYPE != CON
if [ Q$THIS_IS_OPSHUB != QYES ]
then
	THIS_IS_OPSHUB=NO
fi

while getopts hvlxDFa:u:i: OPTION 
do
	case "$OPTION" in
  	 h ) cat $DFO_DOC_DIR/processAB.h | more
	     exit 0 ;;
 	 v ) echo $TOOL_VERSION 
       	     exit 0 ;;
 	 a ) AB="$OPTARG" ;;
	 D ) PROCESSAB_DEBUG="T" ;;
	 F ) FORCE_EXEC=YES ;;
	 l ) PROCESSED_BY_AUTOD=YES	#to mark processAB call as coming from AUTODAILY, for DRS_TYPE=INT
	        ;;
	 i ) export INSTR="$OPTARG" ;;		#needed for OPSHUB processing under CONDOR
 	 u ) export USER="$OPTARG"
	     export HOME="/home/$USER"
	     export PATH
	     PROCESSED_BY_AUTOD=YES 	#to mark processAB call as coming from AUTODAILY, for DRS_TYPE=CON
	     source $HOME/.bashrc   	#CONDOR has no environment variables
	     source $HOME/.dfosrc	
             if [ $THIS_IS_OPSHUB = YES ]
             then
		source $HOME/.dfosrc_opshub_${INSTR}
	     #else
	     #	source $HOME/.dfosrc
	     fi 
	     ;;
	 x ) echo "Available help about esorex and your pipeline:
   esorex --help		general help about esorex
   esorex --recipes		lists recipes of your pipeline
   esorex --help <recipe>	on-line help about recipes
   esorex --man <recipe>	on-line docu about recipes

You may want to edit your general esorex settings under \$HOME/.esorex/esorexrc .
processAB will set: --time | --output-dir | --suppress-prefix.

There might also be the (optional) configuration file \$HOME/.esorex/detmon_{opt|ir}_lg_{instr}.rc 
for the general detmon pipeline.
"
	     exit 0 ;;
 	 ? ) cat $DFO_DOC_DIR/processAB.h | more
	     exit 0 ;;
	esac
done

# =========================================================================
# 0.2 initial checks
# =========================================================================

# check for directory variables which should be set globally in .dfosrc
CHECK=`printenv | grep DFO`
if [ "Q$CHECK" = "Q" ]
then
        echo "*** ERROR: DFO variables not defined. Check ~/.dfosrc and restart."
        exit 1
fi

if [ Q$THIS_IS_PHOENIX != QYES ]
then
	THIS_IS_PHOENIX=NO
fi

if [ $THIS_IS_OPSHUB = YES ]
then
# check if proper environment
	if [ ! -s $DFO_CONFIG_DIR/config.processAB ] && [ Q$INSTR = Q ]
	then
# find out the instrument ...
		FILE_NAME=`echo $AB | sed "s/\./ /" | awk '{print $1}'`
		INSTR=`grep "^SUPPORTED" $DFO_CONFIG_DIR/config.distillery | awk '{print $2,$5}' | grep $FILE_NAME | awk '{print $1}'`
		if [ Q$INSTR = Q ]
		then
			echo "*** ERROR: No configuration file $DFO_CONFIG_DIR/config.processAB found. Check and re-start."
		else
# ... and source the opshub dfosrc  file
			source ~/.dfosrc_opshub_$INSTR
		fi
	fi
fi

if [ ! -s $DFO_CONFIG_DIR/config.processAB ]
then
        echo "*** ERROR: No configuration file $DFO_CONFIG_DIR/config.processAB found. Check and re-start."
        exit 2
fi

# optional DRS_FROM_AB 
if [ $THIS_IS_PHOENIX = YES ]
then
	DRS_FROM_AB=`grep "^DRS_FROM_AB" 	$DFO_CONFIG_DIR/config.processAB | awk '{print $2}'`
	if [ Q$DRS_FROM_AB != QYES ]
	then
		DRS_FROM_AB=NO
	fi

else
	DRS_FROM_AB=NO
fi

# optional key NO_CHECKSUM (makes sense only in rare exceptions)
NO_CHECKSUM=`grep "^NO_CHECKSUM"	$DFO_CONFIG_DIR/config.processAB | awk '{print $2}'`
if [ Q$NO_CHECKSUM != QYES ]
then
	NO_CHECKSUM=NO
fi

case $NO_CHECKSUM in
  "YES" ) NO_CHECKSUM="--no-checksum --no-datamd5"  ;;
  "NO"  ) NO_CHECKSUM="" ;;
esac

# optional key CHECK_SOF_EXIST 
CHECK_SOF_EXIST=`grep "^CHECK_SOF_EXIST"	$DFO_CONFIG_DIR/config.processAB | awk '{print $2}'`
if [ Q$CHECK_SOF_EXIST != QYES ]
then
	CHECK_SOF_EXIST=NO
fi

case $CHECK_SOF_EXIST in
  "YES" ) CHECK_SOF_EXIST="--check-sof-exist" ;;
  "NO"  ) CHECK_SOF_EXIST="" ;;
esac

# check for AB definition
if [ "Q$AB" = "Q" ]
then	
	echo "*** ERROR: No AB defined!"
	exit -1
fi

# check for AB existence
if [ ! -s $DFO_AB_DIR/$AB ]
then
	echo "*** ERROR: $AB: not found in $DFO_AB_DIR. Check and re-start." | tee -a $LOG
	exit -1
fi

if [ ! -s $DFO_CONFIG_DIR/OCA/config.createAB ]
then
	echo "***ERROR: No $DFO_CONFIG_DIR/OCA/config.createAB found. Exit."
	exit -1
elif [ $DRS_FROM_AB = YES ]
then
	DRS_TYPE=`grep "^DRS_TYPE" $DFO_AB_DIR/$AB | awk '{print $2}'`
	echo "***INFO: DRS_TYPE=$DRS_TYPE as read from the AB."
else
	DRS_TYPE=`grep "^DRS_TYPE" $DFO_CONFIG_DIR/OCA/config.createAB | awk '{print $2}'`
fi

# optional ACCEPT_FZ
ACCEPT_FZ=`grep "^ACCEPT_FZ" $DFO_CONFIG_DIR/config.processAB | awk '{print $2}'`
if [ Q$ACCEPT_FZ != QYES ]
then
	ACCEPT_FZ=NO
fi

LOG=`echo $DFS_LOG/$AB | sed "s/ab/rblog/"`

RENAME_SHIFT=`grep "^RENAME_SHIFT"	 $DFO_CONFIG_DIR/config.processAB | awk '{print $2}'`
if [ Q$RENAME_SHIFT = Q ]
then
	RENAME_SHIFT=YES
fi

if [ $THIS_IS_OPSHUB = NO ]
then
	RAWDISP_SUPPORT=`grep "^RAWDISP_SUPPORT" $DFO_CONFIG_DIR/config.processQC | awk '{print $2}'`
	if [ Q$RAWDISP_SUPPORT != QNO ]
	then
		RAWDISP_SUPPORT=YES
	fi
else
	RAWDISP_SUPPORT=NO
fi

# define WORK_AREA
WORK_AREA=`grep "^WORK_AREA" $DFO_CONFIG_DIR/config.processAB | awk '{print $2}'`
WORK_AREA=`eval "echo $WORK_AREA"`

if [ "Q$WORK_AREA" = "Q" ] 
then
	echo "***WARNING: WORK_AREA not defined. Check and re-start." | tee -a $LOG
	exit -1
fi

# create WORK_AREA
if [ ! -d $WORK_AREA ]
then
	mkdir $WORK_AREA

# double check for existance of WORK_AREA (in case e.g. partition hosting WORK_AREA becomes full)
	if [ -d $WORK_AREA ]
	then
		echo "***INFO: WORK_AREA created." | tee -a $LOG
	else
		echo "***ERROR: Could NOT create WORK_AREA." | tee -a $LOG
		exit -1
	fi
fi

AB_WORK=`echo $AB`

# empty unless DRS_TYPE=INT
if [ $DRS_TYPE = INT ]
then
	LIKWID_PATH=`grep "^LIKWID_PATH" $DFO_CONFIG_DIR/config.processAB | awk '{print $2}'`
	LIKWID_CALL=`grep "^LIKWID_CALL" $DFO_CONFIG_DIR/config.processAB | awk '{print $2}'`
	if [ Q$LIKWID_CALL = Q ]
	then
		echo "***ERROR: you must provide \$LIKWID_CALL for DRS_TYPE=INT. Fix and start again."
		exit -1
	fi
fi

export WORK_AREA=`echo $WORK_AREA/${AB_WORK}`

if [ ! -d $WORK_AREA ]
then
	mkdir $WORK_AREA
fi

cd $WORK_AREA
rm -f *

# DEBUG
if [ $PROCESSAB_DEBUG = T ]
then
	echo "
***INFO: DEBUG option set; the environment will be prepared, but the AB will not be processed.
         OK (Y/N) (Y)?"
	read DEBUG_YN
	if [ "Q$DEBUG_YN" = "QN" ]
	then
		echo "Think about it."
		exit
	fi
fi

# =========================================================================
# 0.3 functions
# 0.3.1 getUPDATE
# =========================================================================
getUPDATE(){
date +%Y-%m-%d"T"%H:%M:%S
}

# =========================================================================
# 0.3.2 scanAB
#       Extract updated info into tab file
#	$1: AB
# =========================================================================
scanAB(){
PROCESS_STATUS=`grep "^PROCESS_STATUS" $DFO_AB_DIR/$1 | awk '{print $2}'`
PROCESS_STATUS1=`echo $PROCESS_STATUS | sed "s/CREATED/\.\.\./" | sed "s/SUCCESSFUL/OK/" | sed "s/FAILED/NOK/"`
PLOG=`echo $1 | sed "s/.ab/.rblog/"`
MISS="NONE"
if [ ! -s $DFS_LOG/$PLOG ]
then
	PLOG=RBLOG_NONE
else
	if [ Q"$PROCESS_STATUS1" = QNOK ]
	then
		CHECK_MISSING=`grep "Can NOT get" $DFS_LOG/$PLOG`
		if [ "Q$CHECK_MISSING" != Q ]
		then
			MISS=YES
		fi
	fi
fi
	
AB_TEXEC=`grep "^TEXEC" $DFO_AB_DIR/$1 | awk '{print $2}'`
if [ Q$AB_TEXEC = QNONE ] || [ Q$AB_TEXEC = Q ]
then
	AB_TEXEC=0
else
	AB_TEXEC=`echo $AB_TEXEC | awk '{printf"%3.1f\n",$1/60.}'`
fi

if [ -s $DFO_AB_DIR/$ATAB ]
then
	ACTIVE=NO
	AB_COLOR=`grep "^#STATUS" $DFO_BIN_DIR/getStatusAB | grep " $AMODE $PROCESS_STATUS $ACTIVE WAITING" | awk '{print $6}'`
	AB_COLOR=`grep "^#COLOUR" $DFO_BIN_DIR/getStatusAB | grep " $AB_COLOR " | awk '{print $3}'`

	if [ $THIS_IS_OPSHUB = YES ]
	then
		case $PROCESS_STATUS1 in
		 "OK"  ) QC_STATUS="QCSTATUS_${RAW_TYPE}/$DATE/CSSTATUS" ;;
		 "NOK" ) QC_STATUS="QC_NONE" ;;
		 "..." ) QC_STATUS="QC_NONE" ;;
		esac
	fi

	if [ $THIS_IS_OPSHUB = NO ]
	then
		cat $DFO_AB_DIR/$ATAB |\
 awk '{print abcolor,$2,miss,active,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,proc miss,"RBLOG_"plog,texec,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33}' \
 abcolor=$AB_COLOR active=ACTIVE$ACTIVE miss=MISS$MISS proc=$PROCESS_STATUS1 plog=$PLOG texec=$AB_TEXEC \
 > $TMP_DIR/ATAB_$$
	else
# same as above, plus additional update; QC_STATUS is actually just a link to $DFS_PRODUCT, no reports existing
		cat $DFO_AB_DIR/$ATAB |\
 awk '{print abcolor,$2,miss,active,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,proc miss,"RBLOG_"plog,texec,$24,qcstatus,$26,$27,$28,$29,$30,$31,$32,$33}' \
 abcolor=$AB_COLOR active=ACTIVE$ACTIVE miss=MISS$MISS proc=$PROCESS_STATUS1 plog=$PLOG texec=$AB_TEXEC qcstatus=$QC_STATUS \
 > $TMP_DIR/ATAB_$$
	fi
	mv $TMP_DIR/ATAB_$$ $DFO_AB_DIR/$ATAB
fi
}

# =========================================================================
# 0.3.3 OBSOLETE
# =========================================================================

# =========================================================================
# 1. Preparation
# 1.1 Process logging: we always start logging from scratch
# =========================================================================

echo "===============================================================================================================" | tee $LOG
echo "[`getUPDATE`] processAB: $AB started (version $TOOL_VERSION) " | tee -a $LOG
echo "===============================================================================================================" | tee -a $LOG

# =========================================================================
# 1.2 analyze DRS_TYPE
# =========================================================================

if [ "Q$DRS_TYPE" = "Q" ]
then
	cd
        echo "***ERROR: DRS_TYPE not defined. Check!" | tee -a $LOG
	rm -rf $WORK_AREA	
        exit -1
fi

# within PHOENIX, no check needed
if [ $THIS_IS_PHOENIX = NO ]
then
	grep "^#SUPPORTED" $DFO_BIN_DIR/createAB | awk '{print $2}' > $WORK_AREA/list_DRS
	CHECK_DRS=`grep $DRS_TYPE $WORK_AREA/list_DRS`
	if [ "Q$CHECK_DRS" = "Q" ]
	then
		cd
		echo "***ERROR: $DRS_TYPE is an unsupported DRS. Exit." | tee -a $LOG
		rm -rf $WORK_AREA	
		exit -1
	fi
fi

# =========================================================================
# 1.3 Check for MAXN_RAW
# =========================================================================

RAW_TYPE=`grep RAW_TYPE 	$DFO_AB_DIR/$AB | awk '{print $2}'`
N_RAW=`grep "^RAWFILE" 		$DFO_AB_DIR/$AB | wc -l`

MAXN_RAWT=`grep "^MAXN_RAW"	$DFO_CONFIG_DIR/config.processAB | grep "[[:space:]]${RAW_TYPE}[[:space:]]" | awk '{print $3}' | head -1`

if [ Q$MAXN_RAWT != Q ]
then
	MAXN_RAW=$MAXN_RAWT
fi

if [ $N_RAW -gt $MAXN_RAW ] && [ $FORCE_EXEC = N ] && [ $THIS_IS_OPSHUB = NO ] 
then
	echo "***INFO: $AB not executed in incremental mode since it has more than $MAXN_RAW raw input files. You can call it by hand 'processAB -a $AB -F' if you know what you do. Exit." | tee -a $LOG
	echo "***INFO: $AB not executed in incremental mode since it has more than $MAXN_RAW raw input files. You can call it by hand 'processAB -a $AB -F' if you know what you do." > $TMP_DIR/processABmail_$$
	if [ -s $DFO_MON_DIR/DFO_MESSAGE ]
	then
		CHECK_MESSAGE=`grep "processAB: more than " $DFO_MON_DIR/DFO_MESSAGE | grep $AB | head -1`
	fi

	if [ "Q$CHECK_MESSAGE" = Q ]
	then
		SUBJECT="processAB: more than $MAXN_RAW files found for $AB and $DFO_INSTRUMENT"
		echo "$SUBJECT" >> $DFO_MON_DIR/DFO_MESSAGE
		mail -s "$SUBJECT" $OP_ADDRESS <$TMP_DIR/processABmail_$$
	fi
	rm -f $TMP_DIR/processABmail_$$
	rm -rf $WORK_AREA
	exit 0

elif [ $N_RAW -gt $MAXN_RAW ] && [ $FORCE_EXEC = YES ] && [ $THIS_IS_OPSHUB = NO ]
then
	echo "***INFO: $AB has more than $MAXN_RAW raw files. Did you check that it will likely cause no memory problems (Y/N) (N)?"
	read CHECK_YN
	if [ Q$CHECK_YN != QY ]
	then
		echo "Think about it. Exit."
		exit 0
	else
		echo "OK, we continue ..."
	fi

# in all other cases, continue: N_RAW < $MAXN_RAW
fi

# =========================================================================
# 1.4 parse AB information
# =========================================================================

RECIPE=`grep RECIPE     	$DFO_AB_DIR/$AB | awk '{print $2}' | sed "s/none/NONE/"`
ROOT=`grep PROD_ROOT_NAME	$DFO_AB_DIR/$AB | awk '{print $2}'`
DATE=`grep DATE 		$DFO_AB_DIR/$AB | awk '{print $2}'`
PROD_PATH=`grep PROD_PATH       $DFO_AB_DIR/$AB | awk '{print $2}'`
PROD_PATH=`eval "echo $PROD_PATH"`

# PIPE_VERSION: could be in ESOREX_PLUGIN_DIR ...
PIPE_VERSION=$ESOREX_PLUGIN_DIR
if [ Q$PIPE_VERSION = Q ]
then
# ... or in esorex.rc ...
	PIPE_VERSION=`grep "^esorex.caller.recipe-dir" $HOME/.esorex/esorex.rc | sed "s/esorex.caller.recipe-dir=//"`
fi

# make RECIPE available for modification by pre_plugin
# This is a feature which may be useful for pipelines under commissioning. 
# Just ignore for well-behaved cases.

echo $RECIPE > $WORK_AREA/recipe

# =========================================================================
# 1.4 Look for plugins
#     These are additional pieces of shell code which can be used for non-standard
#     manipulations. There is:
#	COMMON_PLUGIN 	(applied to all RAW_TYPES)
#	PRE_PLUGIN	(applied before COMMON_PLUGIN)
#	POST_PLUGIN	(applied after COMMON_PLUGIN)
#	ERROR_PLUGIN	(applied in case recipe exits with error status)
#	FINAL_PLUGIN	(applied in RENAME_SHIFT, i.e. to call rsync script)
# ==============================================================================

COMMON_PLUGIN=`grep "^COMMON_PLUGIN" $DFO_CONFIG_DIR/config.processAB | awk '{print $2}'`
if [ "Q$COMMON_PLUGIN" = "Q" ]
then
	COMMON_PLUGIN=NONE
fi

PRE_PLUGIN=`grep "^SPEC_PLUGIN" $DFO_CONFIG_DIR/config.processAB | grep "[[:space:]]${RAW_TYPE}[[:space:]]" | awk '{print $3}'`
if [ "Q$PRE_PLUGIN" = "Q" ]
then
	PRE_PLUGIN=NONE
fi

if [ $THIS_IS_OPSHUB = NO ]
then
	POST_PLUGIN=`grep "^SPEC_PLUGIN" $DFO_CONFIG_DIR/config.processAB | grep "[[:space:]]${RAW_TYPE}[[:space:]]" | awk '{print $4}'`
else
# this is better but cannot be generalized because of b/w compatibility
	POST_PLUGIN=`grep "^POST_PLUGIN" $DFO_CONFIG_DIR/config.processAB | awk '{print $2}'`
fi

if [ "Q$POST_PLUGIN" = "Q" ]
then
	POST_PLUGIN=NONE
fi

ERROR_PLUGIN=`grep "^ERROR_PLUGIN" $DFO_CONFIG_DIR/config.processAB | awk '{print $2}'`
if [ "Q$ERROR_PLUGIN" = "Q" ]
then
	ERROR_PLUGIN=NONE
fi

FINAL_PLUGIN=`grep "^FINAL_PLUGIN" $DFO_CONFIG_DIR/config.processAB | sed "s/\&\&$//" | sed "s/^.*\&\&//"`
if [ "Q$FINAL_PLUGIN" = "Q" ]
then
	FINAL_PLUGIN=NONE
fi

# =========================================================================
# 1.5 get recipe control parameters
# 1.5.1 parameters from AB
# =========================================================================

rm -f $WORK_AREA/param_list

grep "^PARAM" $DFO_AB_DIR/$AB | grep -v "NONE" | awk '{print $2}' >> $WORK_AREA/param_list

# =========================================================================
# 1.5.2 parameters from esorex config file
# check for GENERAL section in config file; if found, add the config file to param_list
# =========================================================================

GEN_CONFIG=`grep "^GENERAL[[:space:]]" $DFO_CONFIG_DIR/config.processAB | grep "[[:space:]]${RAW_TYPE}[[:space:]]" | grep "[[:space:]]ANY[[:space:]]" | awk '{print $4}'`

# if found, add in param_list, will be read into ESOREX_PARAMS further down
if [ Q$GEN_CONFIG != Q ]
then
	echo "--recipe-config=~/.esorex/$GEN_CONFIG" >> $WORK_AREA/param_list
fi

# =========================================================================
# 1.6 creating SOF (done for all DRS_TYPEs)
# =========================================================================

cp $DFO_AB_DIR/$AB $WORK_AREA/

grep "^SOF_CONTENT" $DFO_AB_DIR/$AB | awk '{print $2,$3,$4}' | sed "s/^.*/echo \"&\"/" > $WORK_AREA/sof_list
chmod u+x $WORK_AREA/sof_list

# expand pathnames
$WORK_AREA/sof_list > sof

# for pipelines enabled to process tile-compressed files (.fits.fz):
# we check for existence of $FILE.fz; if found, overwrite $FILE in sof, since then no download needed
if [ $ACCEPT_FZ = YES ]
then
	cp sof sof_orig
	for FILE in `cat sof | awk '{print $1}'`
	do
		FILEZ=${FILE}.fz
		if [ ! -f $FILE ] && [ -f $FILEZ ]
		then
			cat sof_orig | sed "s|${FILE} |$FILEZ |" > sof_orig2
			mv sof_orig2 sof_orig
			echo "${FILE}.fz found, replaced in sof"
		fi
	done
	cp sof_orig sof
fi

# =========================================================================
# 1.7 if defined, execute PRE-plugin now; here is a chance to modify e.g.
#        the param_list or the DO_CATG
# =========================================================================
if [ $PRE_PLUGIN != "NONE" ]
then
	echo "[`getUPDATE`] Execute $PRE_PLUGIN " | tee -a $LOG
	eval "$DFO_BIN_DIR/$PRE_PLUGIN $AB" | tee -a $LOG
	echo "" | tee -a $LOG
fi

if [ $COMMON_PLUGIN != "NONE" ] && [ $THIS_IS_OPSHUB = YES ]
then
	echo "[`getUPDATE`] Execute $COMMON_PLUGIN" | tee -a $LOG
	eval "$DFO_CONFIG_DIR/$COMMON_PLUGIN $AB"
fi

# =========================================================================
# 1.8 Finish RECIPE and param_list (could have been modified by PRE_PLUGIN)
# =========================================================================

if [ -s $WORK_AREA/recipe ]
then
	RECIPE=`cat $WORK_AREA/recipe`
fi

echo ""
echo "[`getUPDATE`] start processing $AB (RECIPE: $RECIPE)" | tee -a $LOG

echo "  RAW_TYPE:	$RAW_TYPE"     | tee -a $LOG
echo "  RECIPE:	$RECIPE" 	       | tee -a $LOG
echo "  VERSION:	$PIPE_VERSION" | tee -a $LOG
echo "  Setup for input files:"        | tee -a $LOG

grep "^RAW_MATCH_KEY" $DFO_AB_DIR/$AB | awk '{print $2}' | sed "s/^.*/    &/" | tee -a $LOG

if [ -s $WORK_AREA/param_list ]
then
	PARAMS=`cat $WORK_AREA/param_list     | grep -v "recipe-config" | tr "\012" " "`
	ESOREX_PARAMS=`cat $WORK_AREA/param_list | grep "recipe-config" | tr "\012" " "`
	echo "  Non-default parameters:" | tee -a $LOG
	if [ Q$ESOREX_PARAMS != Q ]
	then
		echo "$ESOREX_PARAMS" | sed "s/^.*/    &/" | tee -a $LOG
	fi

	echo "$PARAMS"        | sed "s/^.*/    &/" | tee -a $LOG
	echo "" | tee -a $LOG
else
        echo "  Parameters: all default" | tee -a $LOG
	echo "" | tee -a $LOG
fi

if [ $THIS_IS_OPSHUB = YES ]
then
	echo "  \$DFO_RAW_DIR:	$DFO_RAW_DIR"        | tee -a $LOG
	echo "  \$DFO_CAL_DIR:	$DFO_CAL_DIR"        | tee -a $LOG
fi

# ================================================================================
# 1.9 Check for $PROD_PATH existing
# ================================================================================

# remove DATE from PROD_PATH
PROD_PATH1=`echo $PROD_PATH | sed "s/20[0-9][0-9]-[0-1][0-9]-[0-3][0-9]//"`
if [ ! -d $PROD_PATH1 ]
then
	mkdir $PROD_PATH1 2>/dev/null
	echo "***INFO: $PROD_PATH1 created."
fi

if [ ! -d $PROD_PATH ]
then
	mkdir $PROD_PATH 2>/dev/null
	echo "***INFO: $PROD_PATH created."
fi

# =========================================================================
# 2. Launch recipe
# =========================================================================

echo "  Processing ..."
echo "-------------------------------------------------------------------------------------------------" >> $LOG

# set flag for ACTIVE in ATAB file
ATAB=`echo $AB | sed "s/.ab/.tab/"`
AMODE=`grep "^DPR_CATG" $DFO_AB_DIR/$AB | awk '{print $2}' | sed "s/TECHNICAL/CALIB/" | sed "s/TEST/CALIB/" | sed "s/ACQUISITION/CALIB/"`

if [ -s $DFO_AB_DIR/$AB ]
then
	ACTIVE=YES
	AB_COLOR=`grep "^#STATUS" $DFO_BIN_DIR/getStatusAB | grep " $AMODE CREATED $ACTIVE WAITING" | awk '{print $6}'`
	AB_COLOR=`grep "^#COLOUR" $DFO_BIN_DIR/getStatusAB | grep " $AB_COLOR " | awk '{print $3}'`

# at that stage PLOG is just a predicted name, but it is considered useful to have the PLOG link already during execution
	PLOG=`echo $AB | sed "s/.ab/.rblog/"`

	if [ -s $DFO_AB_DIR/$ATAB ]
	then
		cat $DFO_AB_DIR/$ATAB |\
 awk '{print abcolor,$2,"MISSNONE",active,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,"...","RBLOG_"plog,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33}' \
 abcolor=$AB_COLOR active=ACTIVE$ACTIVE plog=$PLOG \
 > $TMP_DIR/ATAB_$$
		mv $TMP_DIR/ATAB_$$ $DFO_AB_DIR/$ATAB
	fi
fi

# ================================================================================
# 2.1 Check for existence of REAL MCALIBs on local disk, download from CDB as needed
#     (only if recipe is defined)
# ================================================================================

if [ $RECIPE = "NONE" ]
then
	if [ $THIS_IS_OPSHUB = NO ]
	then
		echo "  ... no recipe defined for ${RAW_TYPE}, no mcalib download." | tee -a $LOG
	else
		echo "  ... no recipe defined for ${RAW_TYPE}." | tee -a $LOG
	fi
else

# $DFO_MON_DIR/MCAL_DOWNLOAD: used to manage individual mcalib downloads for later deletion by cleanupProducts
	if [ ! -s $DFO_MON_DIR/MCAL_DOWNLOAD ]
	then
		cat > $DFO_MON_DIR/MCAL_DOWNLOAD <<EOT
# This is the list of mcalib files downloaded by ngasClient@processAB. 
# They should be deleted eventually.
EOT
	fi

	PATTERN="^MCALIB[[:space:]].*[[:space:]]REAL[[:space:]]"
	for M in `eval "egrep '${PATTERN}' $DFO_AB_DIR/$AB" | grep -v DFS_PRODUCT | awk '{print $3}'`
#OLD v2.4: for M in `eval "egrep '${PATTERN}' $DFO_AB_DIR/$AB" |  awk '{print $3}'`
	do
		M="`eval echo $M`"
		MC="`basename $M`"
		MH=`echo $MC | sed "s/tfits/hdr/" | sed "s/fits/hdr/"`
		MD="`dirname $M`"
		if [ ! -f $M ]
		then
			echo "Requesting $MC from the CDB..." | tee -a $LOG
			ngasClient -c $MC > /dev/null
			if [ -f $MC ]
			then
				if [ ! -d ${MD} ]
				then	
					mkdir ${MD}
				fi
				mv ${MC} ${MD}
# if $MC = hdr file existing, remove (it might confuse ABbuilder)
				rm -f ${MD}/${MH}
				echo "${MD}/${MC}" >> $DFO_MON_DIR/MCAL_DOWNLOAD
				echo "... done successfully." | tee -a $LOG
			else
				echo "EXIT_CODE = 1" | tee -a $LOG
				echo "***ERROR: Can NOT get $MC from CDB. Exit and check." | tee -a $LOG
			fi
		fi
	done
fi

# ================================================================================
# 2.2 RAWFILEs
#     RAWDISP_SUPPORT=YES: always downloaded, because of qc_rawdisp.py being called later 
#     RAWDISP_SUPPORT=NO: download for processing (i.e. if $RECIPE != "NONE")
#     RASSOCs are never downloaded
# ================================================================================

if ( [ $RAWDISP_SUPPORT = YES ] || ( [ $RAWDISP_SUPPORT = NO ] && [ $RECIPE != "NONE" ] ))
then
	for R in `grep '^RAWFILE[[:space:]]' $DFO_AB_DIR/$AB | awk '{print $2}' | grep -v NONE`
	do
		R="`eval echo $R`"
		RC="`basename $R`"
		RD="`dirname  $R`"
		RH=`echo $RC | sed "s/fits/hdr/"`

# ${R}.fz: tile-compressed files, e.g. VIRCAM
		if [ ! -f $R ] && [ ! -f ${R}.fz ]
		then
			echo "Requesting $RC from NGAS ... (header will be updated)" | tee -a $LOG
			ngasClient -f $RC > /dev/null
			if [ -f $RC ]
			then
				if [ ! -d ${RD} ]
				then
					mkdir ${RD}
				fi
				mv ${RC} ${RD}
				rm -f $RD/$RH
				echo "... done successfully." | tee -a $LOG
			else
				echo "EXIT_CODE = 1" | tee -a $LOG
				echo "***ERROR: Can NOT get $RC from NGAS. Exit and check."  | tee -a $LOG
			fi
		fi
	done
fi

# ================================================================================
# 2.3 Run Pipeline... (if RECIPE is defined)
# ================================================================================

if [ $RECIPE != "NONE" ]
then
	case $DRS_TYPE in
		"CPL"|"CON" ) echo "
RECIPE CALL: 
esorex --time --output-dir=$WORK_AREA --suppress-prefix $NO_CHECKSUM $CHECK_SOF_EXIST $ESOREX_PARAMS $RECIPE $PARAMS sof " >> $LOG 2>&1
			if [ $PROCESSAB_DEBUG != "T" ]
			then
				esorex --time --output-dir=$WORK_AREA --suppress-prefix $NO_CHECKSUM $CHECK_SOF_EXIST $ESOREX_PARAMS $RECIPE $PARAMS sof >> $LOG 2>&1
			else
				echo "
cd $WORK_AREA"
				if [ $THIS_IS_OPSHUB = YES ]
				then
					echo "source $HOME/.dfosrc_opshub_$DFO_INSTRUMENT"
				fi
				echo "esorex --time --output-dir=$WORK_AREA --suppress-prefix $NO_CHECKSUM $CHECK_SOF_EXIST $ESOREX_PARAMS $RECIPE $PARAMS sof"
				echo "
Now you may want to execute this esorex call manually. 
Don't forget to delete $WORK_AREA afterwards. Hit return:"
				read input
				exit
			fi
			;;

		"INT" ) echo "
RECIPE CALL:
$LIKWID_PATH/likwid-pin -c $LIKWID_CALL esorex --time --output-dir=$WORK_AREA --suppress-prefix $NO_CHECKSUM $CHECK_SOF_EXIST $ESOREX_PARAMS $RECIPE $PARAMS sof " >> $LOG 2>&1
			if [ $PROCESSAB_DEBUG != "T" ]
			then
				$LIKWID_PATH/likwid-pin -c $LIKWID_CALL esorex --time --output-dir=$WORK_AREA --suppress-prefix $NO_CHECKSUM $CHECK_SOF_EXIST $ESOREX_PARAMS $RECIPE $PARAMS sof >> $LOG 2>&1
			else
				echo "
cd $WORK_AREA"
				if [ $THIS_IS_OPSHUB = YES ]
				then
					echo "source $HOME/.dfosrc_opshub_$DFO_INSTRUMENT"
				fi
				echo "$LIKWID_PATH/likwid-pin -c $LIKWID_CALL esorex --time --output-dir=$WORK_AREA --suppress-prefix $NO_CHECKSUM $CHECK_SOF_EXIST $ESOREX_PARAMS $RECIPE $PARAMS sof"
				echo "
Now you may want to execute this esorex call manually. 
Don't forget to delete $WORK_AREA afterwards. Hit return:"
				read input
				exit
			fi
			;;

		*   ) echo "Unsupported DRS: $DRS_TYPE." ; exit -1 ;;
	esac
fi

EXIT_CODE=$?	
echo "EXIT_CODE = $EXIT_CODE" >> $LOG 

# =========================================================================
# 3. Verify results
# =========================================================================

if [ $RECIPE = "NONE" ] && [ $THIS_IS_OPSHUB = NO ]
then
	LINE_SOFSECT=`grep -n "SOF section starts" $DFO_AB_DIR/$AB | sed "s/:# =====.*//" | awk '{print $1-1}'`
	cat $DFO_AB_DIR/$AB | awk '{if (NR < n ) {print $0}}' n=$LINE_SOFSECT | sed "s/PROCESS_STATUS.*/PROCESS_STATUS  SUCCESSFUL/" > $WORK_AREA/AB_$$
	echo "AB_STATUS	- processed by 'processAB'	on `date` by `whoami` on `hostname`" >> $WORK_AREA/AB_$$
        cat $DFO_AB_DIR/$AB | awk '{if (NR >= n ) {print $0}}' n=$LINE_SOFSECT >> $WORK_AREA/AB_$$
        mv $WORK_AREA/AB_$$ $DFO_AB_DIR/$AB
fi

if [ $RECIPE != "NONE" ] 
then
	CHECK=`ls | grep fits | wc -l`
	if [ $CHECK = "0" ] || [ "Q$EXIT_CODE" != "Q0" ]
	then
		ALREADY_PROC=`grep "processed by" $DFO_AB_DIR/$AB | head -1`
		LINE_SOFSECT=`grep -n "SOF section starts" $DFO_AB_DIR/$AB | sed "s/:# =====.*//" | awk '{print $1-1}'`
		cat $DFO_AB_DIR/$AB | awk '{if (NR < n ) {print $0}}' n=$LINE_SOFSECT | sed "s/PROCESS_STATUS.*/PROCESS_STATUS  FAILED/" > $WORK_AREA/AB_$$
		echo "AB_STATUS	- processed by 'processAB'	on `date` by `whoami` on `hostname`" >> $WORK_AREA/AB_$$
	        cat $DFO_AB_DIR/$AB | awk '{if (NR >= n ) {print $0}}' n=$LINE_SOFSECT >> $WORK_AREA/AB_$$
	        mv $WORK_AREA/AB_$$ $DFO_AB_DIR/$AB

# getDelay disabled with v2.7.6

		echo "[`getUPDATE`] *** WARNING: ... terminated unsuccessful." | tee -a $LOG
		echo ""
		echo "===============================================================================================================" | tee -a $LOG
		echo "[`getUPDATE`] processAB: finished. " | tee -a $LOG
		echo "===============================================================================================================" | tee -a $LOG

		if [ $ERROR_PLUGIN != "NONE" ]
		then
			eval "$DFO_BIN_DIR/$ERROR_PLUGIN $AB"
		fi

		rm -rf $WORK_AREA 
		scanAB ${AB}	
		exit 0

	else
		PIPE_ID=`dfits *fits | grep "PIPE ID" | sed "s/^.* PIPE ID =//" | awk '{print $1}' | sed "s/'//g" | tail -1`
		ALREADY_PROC=`grep "processed by" $DFO_AB_DIR/$AB | head -1`
		LINE_SOFSECT=`grep -n "SOF section starts" $DFO_AB_DIR/$AB | sed "s/:# =====.*//" | awk '{print $1-1}'`
		cat $DFO_AB_DIR/$AB | awk '{if (NR < n ) {print $0}}' n=$LINE_SOFSECT | sed "s/PROCESS_STATUS.*/PROCESS_STATUS  SUCCESSFUL/" > $WORK_AREA/AB_$$
		echo "AB_STATUS	- processed by 'processAB'	on `date` by `whoami` on `hostname` with '$PIPE_ID'" >> $WORK_AREA/AB_$$
	        cat $DFO_AB_DIR/$AB | awk '{if (NR >= n ) {print $0}}' n=$LINE_SOFSECT >> $WORK_AREA/AB_$$
	        mv $WORK_AREA/AB_$$ $DFO_AB_DIR/$AB

# disabled with v2.7.6

		echo "[`getUPDATE`] *** INFO: ... terminated successful." | tee -a $LOG
	fi
	echo "-------------------------------------------------------------------------------------------------" 
fi

# =========================================================================
# 4. Set PIPEFILE correctly
# =========================================================================

if [ $RECIPE != "NONE" ]
then
	rm -f $WORK_AREA/product_list
	grep "^PRO_CATG[[:space:]]" $DFO_CONFIG_DIR/config.processAB |\
	 grep -v "\.paf" |\
	 grep "[[:space:]]${RECIPE}[[:space:]]" |\
	 egrep "[[:space:]]${RAW_TYPE}[[:space:]]|[[:space:]]${RAW_TYPE}$" |\
	 awk '{print $3}' |\
	 sort -u \
	 > $WORK_AREA/product_list

	if [ ! -s $WORK_AREA/product_list ]
	then
		echo "[`getUPDATE`] ***ERROR: no products defined. Check $DFO_CONFIG_DIR/config.processAB!" | tee -a $LOG
	else
		for FILE in `cat $WORK_AREA/product_list`
		do
			if [ ! -s $FILE ]
			then
				echo "[`getUPDATE`] ***ERROR: $FILE expected but not found. Check out!"
				continue
			fi
			chmod u+w $FILE
	
# improved in v1.7.2 [MNe]: make ${RAW_TYPE} unique
			EXT=`grep "[[:space:]]$FILE" $DFO_CONFIG_DIR/config.processAB  | grep -v "^#" | grep $RECIPE | egrep "[[:space:]]${RAW_TYPE}[[:space:]]|[[:space:]]${RAW_TYPE}$" | awk '{print $4}'`
			PIPEFILE=`echo ${ROOT}_${EXT}`
			replacekey -p PIPEFILE -v $PIPEFILE $FILE 1>/dev/null
		done
	fi
fi

# =========================================================================
# 5. Apply plugins
# 5.1 Common plugin (for DFOS and PHOENIX; OPSHUB: called already)
# =========================================================================

if [ $COMMON_PLUGIN != "NONE" ] && [ $THIS_IS_OPSHUB = NO ]
then
	echo "[`getUPDATE`] Execute $COMMON_PLUGIN" | tee -a $LOG
	eval "$DFO_BIN_DIR/$COMMON_PLUGIN $AB"
fi

# =========================================================================
# 5.2 If defined, execute POST_PLUGIN
#     Here is another chance to modify RECIPE ...
# =========================================================================

if [ $POST_PLUGIN != "NONE" ]
then
	echo "" | tee -a $LOG
	echo "[`getUPDATE`] Execute $POST_PLUGIN" | tee -a $LOG
	if [ $THIS_IS_OPSHUB = NO ]
	then
		eval "$DFO_BIN_DIR/$POST_PLUGIN $AB" | tee -a $LOG
	else
# OPSHUB needs a different directory, unfortunately
		eval "$DFO_CONFIG_DIR/$POST_PLUGIN $AB" | tee -a $LOG
	fi
fi

RECIPE=`cat $WORK_AREA/recipe`

# =========================================================================
# 6. Move to final directories
# =========================================================================

if [ $RECIPE != "NONE" ]
then
	echo "	Output ..."

	rm -f $WORK_AREA/file_list
	ls | grep "fits$" >  $WORK_AREA/file_list

	if [ ! -s $WORK_AREA/file_list ]
	then
		echo "***ERROR: No product files found!" | tee -a $LOG
		rm -rf $WORK_AREA $WORK_AREA

		scanAB ${AB}	
		exit -1
	fi

# rename and shift
	if [ $RENAME_SHIFT = YES ]
	then
		for FILE in `cat $WORK_AREA/file_list`
		do
# RAW_TYPE: either at the end or with white space
			INDEX_EXT=`grep "^PRO_CATG" $DFO_CONFIG_DIR/config.processAB | grep "[[:space:]]$RECIPE[[:space:]]" | egrep "	$FILE| $FILE" | egrep "[[:space:]]${RAW_TYPE}$|[[:space:]]${RAW_TYPE}[[:space:]]" | awk '{print $4}'`
			if [ "Q$INDEX_EXT" = "Q" ]
			then
				echo "***WARNING: RENAME_SHIFT enabled, but $FILE not configured in config.processAB."
			else
				chmod u+w ${FILE}
				eval "mv ${FILE} ${PROD_PATH}/${ROOT}_${INDEX_EXT}"
			fi
		done
	fi
fi

# =========================================================================
# 7. Finish
# =========================================================================

echo "===============================================================================================================" | tee -a $LOG
echo ""

echo "[`getUPDATE`] end processing $AB (RECIPE: $RECIPE)" | tee -a $LOG
echo "===============================================================================================================" | tee -a $LOG

# =========================================================================
# get execution time
# =========================================================================

START_TIME=`grep "start processing" $LOG | head -1 | awk '{print $1}' | sed "s/:$//" | sed "s/\[//" | sed "s/\]//"`
END_TIME=`grep "end processing"     $LOG | tail -1 | awk '{print $1}' | sed "s/:$//" | sed "s/\[//" | sed "s/\]//"`
if [ "Q$START_TIME" = "Q" ] || [ "Q$END_TIME" = "Q" ]
then
	TEXEC=0
else
	START_SECONDS=`echo $START_TIME | sed "s/:/ /g" | sed "s/T/ /" | awk '{print $2*3600+$3*60+$4}'`
	DATE1=`echo $START_TIME | sed "s/T/ /" | awk '{print $1}'`

	END_SECONDS=`echo $END_TIME | sed "s/:/ /g" | sed "s/T/ /" | awk '{print $2*3600+$3*60+$4}'`
	DATE2=`echo $END_TIME | sed "s/T/ /" | awk '{print $1}'`

	if [ $DATE1 = $DATE2 ]
	then
		TEXEC=`echo $END_SECONDS $START_SECONDS | awk '{print $1-$2}'`
	else
		TEXEC=`echo $END_SECONDS $START_SECONDS | awk '{print $1+86400-$2}'`
	fi
fi

sed "s/TEXEC.*/TEXEC		$TEXEC/" $DFO_AB_DIR/$AB > AB
mv AB $DFO_AB_DIR/$AB

cd

if [ "Q$RENAME_SHIFT" = "QYES" ]
then
	rm -rf $WORK_AREA
	echo "***INFO: Products have been moved to ${PROD_PATH}."
	if [ "$FINAL_PLUGIN" != "NONE" ]
	then
		eval "$DFO_BIN_DIR/$FINAL_PLUGIN $AB"
	fi
else
	echo "***INFO: Products are in $WORK_AREA."
fi

scanAB ${AB}
exit 0
