#!/bin/sh
# PURPOSE:      renameProducts: rename calib and science products to QC convention
#		(for use in mcalib archive)
# AUTHOR:       Reinhard Hanuschik / ESO
# VERSIONS:     1.0 -- NOVEMBER 2002 (UVES-FIBRE)
#		1.1 -- common script (2003-02-12)
#		1.2 -- includes version for PSO package (2004-04-15)
#		1.3 -- includes SCIENCE renaming (2004-05-04)
#		1.3.1- includes check for PIPEFILE scheme (2004-08-10)
#		1.4 -- supports dfosLog; call syntax changed (2004-08-12)
#		1.4.1- modified treatment in case of PIPEFILE error (2004-10-01)
#		1.4.2- some bugs removed, PROD_STRING deprecated (2004-10-25)
#		1.5 -- uses fitsreport to read parameters; no need for mjd2date anymore; 
#		       call syntax changed to comply with other dfos tools (2004-10-26)
#		1.5.1- inconsistency with %% in the config file removed (PARSTRING; syntax has changed here!) (2004-11-26)
#		1.5.2- improved handling of PRO.CATG strings (2005-02-15)
#		1.5.3- even better handling of PRO.CATG strings (2005-03-10)
#		1.5.4- bug fixed with chmod for SCIENCE case (2005-03-17)
#		1.5.5- warning for filenames longer than 80 chars added (2005-05-04)
#		1.5.6- dfosLog suspended (2006-05-18)
#		1.5.7- setConfigVar mechanism for external control of CHECK_YN (for processPreImg) (2006-06-20)
#		1.5.8- changed to rename, for SCIENCE, only files starting with r. (2007-07-10)
#		1.5.9- introducing SPECIAL_PLUGIN (e.g. to constrain filename length) (2007-09-13)
#		1.5.10- introducing PRE_PLUGIN (e.g. to deal with strange keyword content) (2007-09-28) (SMo)
#		1.5.11- more restrictive check for filenames longer than 68 characters (2007-11-20)
#		1.6 -- new mode: GEN, to rename static calibration files in $GEN_CALDIR (2008-06-12)
#		1.6.1- bug fixed for case of pre-existing files with same PIPEFILE (line 280) (2008-10-22)
# 		1.6.2- code improved for MODE=SCIENCE (lines :423 and :425) (2010-09-20)
#		1.7 -- phoenix v2 support: non-std config file for phoenix versioning supported (2015-02-10)
#		1.8 -- PAR naming scheme removed (obsolete) (2017-02-07)
# PARAMETERS: 	-d DATE
#		-m MODE (CALIB | SCIENCE | GEN)
#		-c CONFIG_FILE (PHOENIX only)	
# OUTPUT:	rn_files (executable)
# CONFIG:	config.renameProducts to read the keys; or non-std config file if specified (for PHOENIX)
# TOOLS CALLED:	fitsreport
#
# COMMENTS:    	- creates for each input frame a new file name that is 
#		  based on fits header keywords
#		- prints the new file name to the output file rn_files
#		- files are expected as follows:
#			CALIB: 	 $DFO_CAL_DIR/$DATE
#			SCIENCE: $DFO_SCI_DIR/$DATE
#			GEN:	 $GEN_CALDIR
#		  where $DATE is read from -d parameter.
#		- supported schemes: 
#		  CALIB: CALIBNAME, e.g.     GI_PFEX_040404A_Medusa2_H679.7nm_o8.fits
#		  GEN:	 CALIBNAME, e.g.     GI_GRAT_030401A_HRB.fits
#		  SCIENCE: USERSCINAME, e.g. GI_SFEX_12352_2004-04-05T07:57:43.000_Med2_H679.7.fits
# ==============================================================================
TOOL_VERSION=1.8

# ==============================================================================
# 0 Initialization
# 0.1 Check for .dfosrc and config files
# ==============================================================================

CHECK=`printenv | grep DFO`

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

# ================================================================
# 0.2 read options 
# ===============================================================

if [ $# = 0 ] 
then
        cat $DFO_DOC_DIR/renameProducts.h
        exit 0
fi

CONFIG=$DFO_CONFIG_DIR/config.renameProducts

while getopts c:m:d:hv OPTION
do
	case "$OPTION" in
	 v ) echo $TOOL_VERSION
	     exit 0 ;;
	 h ) cat $DFO_DOC_DIR/renameProducts.h
	     exit 0 ;;
	 m ) export MODE=$OPTARG ;;
	 d ) export DATE=$OPTARG ;;
	 c ) CONFIG=$DFO_CONFIG_DIR/$OPTARG ;;
	 ? ) cat $DFO_DOC_DIR/renameProducts.h
	     exit 0 ;;
	 esac
done

# ================================================================
# 0.3 check params
# ===============================================================

if [ Q$THIS_IS_PHOENIX != QYES ] && [ $CONFIG != $DFO_CONFIG_DIR/config.renameProducts ]
then
	echo "***ERROR: the option -c (non-standard config file) is restricted for use within PHOENIX. Exit."
	exit -1
fi

if [ ! -s $CONFIG ]
then
	echo "*** ERROR: no $CONFIG file found. Check!"
	exit -1
fi

if [ Q$MODE = Q ]
then
	echo "*** ERROR: Mode must be CALIB | SCIENCE | GEN. Check and re-start."
	exit -1
fi

if [ $MODE != "CALIB" ] && [ $MODE != "SCIENCE" ] && [ $MODE != "GEN" ]
then
	echo "*** ERROR: Mode must be CALIB | SCIENCE | GEN. Check and re-start."
	exit -1
fi

CHECKD=`echo $DATE | wc -c`
if ( [ $MODE = "SCIENCE" ] || [ $MODE = "CALIB" ] ) && [ $CHECKD != 11 ]
then
        echo "***ERROR: wrong date format: $DATE; should be: 2004-04-04; start again."
        exit -1
fi

if ( [ $MODE = "SCIENCE" ] || [ $MODE = "CALIB" ] ) && [ "Q$DATE" = "Q" ]
then
	echo "***ERROR: you must provide a DATE, format should be 2004-04-04; start again."
	exit -1
fi

if [ $MODE = GEN ]
then
	SOURCE_DIR=`grep "^GEN_CALDIR"	$DFO_CONFIG_DIR/OCA/config.createAB | awk '{print $2}'`
fi
SOURCE_DIR=`eval "echo $SOURCE_DIR"`

if [ ! -d $SOURCE_DIR ]
then
	echo "***ERROR: PATH $SOURCE_DIR does not exist."
	exit -1
fi

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

# new with v1.5.10 (SMo) 
PRE_PLUGIN=`grep "^PRE_PLUGIN"		$DFO_CONFIG_DIR/config.renameProducts | awk '{print $2}'`
if [ "Q$PRE_PLUGIN" = "Q" ]
then
	PRE_PLUGIN=NONE
fi

# ==============================================================================
# 0.4 procedures
# ==============================================================================
# procedure setConfigVar to read variable either from environment, or -if not set- from config file
# needed for pre-IMG
setConfigVar(){
v1="$`echo $1`"
v2="`eval echo $v1`"
if [ -z "${v2}" ] 
then
        eval $1=`grep "^$1" $CONFIG | awk '{print $2}'`
        v2="`eval echo $v1`"
fi      
}

# ==============================================================================
# 0.5 Check if there are files
# ==============================================================================

rm -f $TMP_DIR/file_list

case $MODE in
 "CALIB" )	SOURCE_DIR="$DFO_CAL_DIR/$DATE" ;;
 "SCIENCE" )	SOURCE_DIR="$DFO_SCI_DIR/$DATE" ;;
 "GEN" )	SOURCE_DIR="$SOURCE_DIR" ;;
esac

cd $SOURCE_DIR
# changed to find not yet renamed files (SCIENCE only) (v1.5.8)

case $MODE in
 CALIB ) 	ls | egrep "^r.|^${MCAL_CODE}_" | grep fits > $TMP_DIR/file_list ;;	#PIPEFILE or CALIBNAME
 GEN )		ls | grep fits | grep -v "^${DFO_FILE_NAME}." | grep -v "^${MCAL_CODE}_" > $TMP_DIR/file_list ;;	#no raw files, nor already renamed files
 SCIENCE ) 	ls | grep "^r." | grep fits > $TMP_DIR/file_list ;;			#PIPEFILE
esac

if [ ! -s $TMP_DIR/file_list ]
then
	echo "***INFO: directory checked: $SOURCE_DIR"
	echo "***INFO: No product files found for renaming."
	exit 0
fi

rm -f rn_files rn_files1 

# support external control of $CHECK_YN for processPreImg
setConfigVar CHECK_YN

# ==============================================================================
# 0.6 Create $TMP_DIR/counter, for case matching and versioning
# ==============================================================================

cat > $TMP_DIR/counter << EOT
COUNT=1
for FILE in \`cat $TMP_DIR/version_list | awk '{print \$1}'\`
do
	CALIB_NAME=\`grep \$FILE $TMP_DIR/version_list | awk '{print \$2}'\`
	case \$COUNT in 
EOT

grep "^VERSION" $CONFIG | awk '{print $2,$3}' | sed "s/ /\") VERSION=/" | sed "s/^.*/		\"&;;/" >> $TMP_DIR/counter

cat >> $TMP_DIR/counter <<EOT
		*) VERSION=YY
		echo "\$FILE: \$COUNT \$VERSION; check out."
		exit;;
	esac
	CALIB_NAME=\`echo \$CALIB_NAME | sed "s/VERSION/\$VERSION/"\`
	echo "mv \$FILE \$CALIB_NAME"
	COUNT=\`echo \$COUNT | awk '{print \$1+1}'\`
done
exit
EOT

chmod u+x $TMP_DIR/counter

# ==============================================================================
# 0.7 procedure set_DFO_STATUS
# This is needed since the DFO flag is set by rn_files (i.e. if the renaming becomes real)
# ==============================================================================

set_DFO_STATUS(){
cat >> rn_files <<EOT
UPDATE=\`date +%Y-%m-%d"T"%H:%M:%S\`
echo "$DFO_STATUS $DATE \$UPDATE" >> $DFO_MON_DIR/DFO_STATUS
EOT
}

# ==============================================================================
# 1. create parser_spec for the SPECIFIC part
# ==============================================================================

echo ""

echo " 1. Renaming for mode $MODE ..."

rm -f $TMP_DIR/parser_spec 

# get info for fitsreport_renameProducts.cfg
grep "^SPECIFIC_ALL" 	 $CONFIG | sed "s/SPECIFIC_ALL//" | tr " " "@" | sed "s/^@*//" | sed "s/@/ /g" | sed "s/^	*//" > $TMP_DIR/fitsreport_renameProducts.cfg
grep "^SPECIFIC_${MODE}" $CONFIG | sed "s/SPECIFIC_${MODE}//" | tr " " "@" | sed "s/^@*//" | sed "s/@/ /g" | sed "s/^	*//"  >> $TMP_DIR/fitsreport_renameProducts.cfg
PWD_ORIG=$PWD

cd $DFO_CONFIG_DIR
ln -sf $TMP_DIR/fitsreport_renameProducts.cfg .
cd $PWD_ORIG

# required for cases with very high number of files (then loop: safer but slower)
rm -f $TMP_DIR/results
CHECK_NUMBER=`ls | grep fits | wc -l`
if [ "$CHECK_NUMBER" -gt 1000 ]
then 
	for F in `ls | grep fits`
	do
		fitsreport -c fitsreport_renameProducts.cfg $F | grep -v log4cplus >> $TMP_DIR/results
	done
else
	fitsreport -c fitsreport_renameProducts.cfg *fits | grep -v log4cplus >> $TMP_DIR/results
fi

# new with v1.5.10 (SMo): execute optional plugin

if [ "Q$PRE_PLUGIN" != "QNONE" ]
then
	eval "$DFO_BIN_DIR/$PRE_PLUGIN"
fi

#create parser_spec
grep "^SPECIFIC" $CONFIG | grep $MODE | grep "SEQORD" | sed "s/^.*SEQORD/SEQORD/" | sed "s/SEQORD../&=\`grep \^\$1 \$TMP_DIR\/results \| awk \'{print &}\' \|/" | sed "s/&&//"g | sed "s/^.*/&\`/" | sed "s/SEQORD/FIELD/" | sed "s/SEQORD/\$/" | grep -v FIELD01 > $TMP_DIR/parser_spec
cat $TMP_DIR/parser_spec | sed "s/=.*//" | sed "s/^.*/\$&/" | awk '{printf"%s ",$0}' | sed "s/^.*/echo &/" >> $TMP_DIR/parser_spec ; chmod u+x $TMP_DIR/parser_spec

# ==============================================================================
# 2. Loop on files: CALIB case
# ==============================================================================

if [ $MODE = "CALIB" ] || [ $MODE = "GEN" ]
then
	for FILE in `cat $TMP_DIR/file_list`
	do

# ==============================================================================
# 2.1 General CALIBNAME part
# ==============================================================================

# GEN: check for essential fits keys MJD-OBS
		if [ $MODE = GEN ]
		then
			INSTRUME=`dfits $FILE | fitsort -d INSTRUME | awk '{print $2}'`
			if [ Q$INSTRUME = Q ]
			then
				echo "*** ERROR: $FILE has no INSTRUME key, can't rename. Use modhead to fix and retry."
				continue
			fi
			MJD_OBS=`dfits $FILE | fitsort -d MJD-OBS | awk '{print $2}'`
			if [ Q$MJD_OBS = Q ]
			then
				echo "*** ERROR: $FILE has no MJD-OBS key, can't rename. Use modhead to fix and retry."
				continue
			fi
		fi

		PRO_CATG=`dfits $FILE | fitsort -d PRO.CATG | awk '{print $2}'`
		if [ Q$PRO_CATG = Q ]
		then
			echo "*** ERROR: $FILE has no PRO.CATG key, can't rename. Use modhead to fix and retry."
			continue
		fi

# SUFFIX
		SUFFIX=`echo $FILE | sed "s/^.*\.tfits/tfits/" | sed "s/^.*\.fits/fits/"`

# dummy for VERSION
		VERSION="A"

		PIPEFILE=`grep $FILE $TMP_DIR/results | awk '{print $2}' | sort -u`
		CHECK=`echo $PIPEFILE | grep "r." | grep $DFO_FILE_NAME`

		if [ "Q$CHECK" != "Q$PIPEFILE" ] && [ $MODE != GEN ]
		then
			echo "*** ERROR for ${FILE}: $PIPEFILE does not comply with PIPEFILE rule. No renaming possible."
			continue 
		fi

# special DATE format for mcalibs
		if [ $MODE != GEN ]
		then
	   		DATE2=`echo $DATE | cut -c3-10 | sed "s/-//g"`
		else
			MJD_OBS=`dfits $FILE | fitsort -d MJD-OBS | awk '{print $2}' | awk '{printf"%10.5f\n", $1-0.5-off/24}' off=$DFO_OFFSET`
			DATE2=`qcdate $MJD_OBS | cut -c3-10 | sed "s/-//g"`
		fi

# ==============================================================================
# 2.2   Specific CALIBNAME part: read from config file
# ==============================================================================

# wrap PRO_CATG to always have unique strings
		rm -f $TMP_DIR/code_list
		grep "^CODE" $CONFIG | awk '{print $1,$2,"yz"$3"yz",$4,$5}' > $TMP_DIR/code_list

		RAW_TYPE=`grep "yz${PRO_CATG}yz" $TMP_DIR/code_list | awk '{print $4}'`
		if [ Q$RAW_TYPE = "Q" ]
		then
			echo "*** WARNING: $FILE: unknown PRO_CATG $PRO_CATG. Skipped."
			continue
		fi
		CODE=`grep "yz${PRO_CATG}yz" $TMP_DIR/code_list | grep $RAW_TYPE | awk '{print $2}'`
		CASE=`grep "^CASE" $CONFIG | grep "[[:space:]]${RAW_TYPE}[[:space:]]" | awk '{print $3}'`

		PARSTRING=""
		PARSTRING=`grep "^PARSTRING" $CONFIG | grep "[[:space:]]${CASE}[[:space:]]" | sed "s/&&$//" | sed "s/^.*&&//"`
		if [ "Q$PARSTRING" != "Q" ]
		then
			PAR_STRING=`eval "$TMP_DIR/parser_spec $FILE | $PARSTRING"`
		else
			PAR_STRING="NONE"
		fi

# ==============================================================================
# 2.3 Create CALIBNAME, w/o versioning
# ==============================================================================
	
		case $MODE in
		 "CALIB" ) 	echo "$FILE ${MCAL_CODE}_${CODE}_${DATE2}VERSION_${PAR_STRING}.${SUFFIX} $PRO_CATG" >> rn_files ;;
		 "GEN" ) 	echo "$FILE ${MCAL_CODE}_${CODE}_${DATE2}A_${PAR_STRING}.${SUFFIX} $PRO_CATG" >> rn_files ;;
		esac
	done
fi

# ==============================================================================
# 3. Loop on files: SCIENCE case
# ==============================================================================

if [ $MODE = "SCIENCE" ] 
then
	for FILE in `cat $TMP_DIR/file_list`
	do

# ==============================================================================
# 3.1 General USERSCINAME part
# ==============================================================================

# SUFFIX
		SUFFIX=`echo $FILE | sed "s/^.*\.tfits/tfits/" | sed "s/^.*\.fits/fits/"`

# PRO.CATG, DATETIME
		PRO_CATG=`dfits $FILE | fitsort -d "HIERARCH ESO PRO CATG" | awk '{print $2}'`
		DATETIME=`dfits $FILE | fitsort -d "PIPEFILE" | awk '{print $2}' | sed "s/\./ /g" | awk '{print $3"."$4}' | sed "s/_.*//"`

# OBS.ID
		OBS_ID=`dfits $FILE | fitsort -d "HIERARCH ESO OBS ID" | awk '{print $2}'`

# ==============================================================================
# 3.2 Specific USERSCINAME part: read from config file
# ==============================================================================

# wrap PRO_CATG to always have unique strings
		rm -f $TMP_DIR/code_list
		grep "^CODE" $CONFIG | awk '{print $1,$2,"yz"$3"yz",$4,$5}' > $TMP_DIR/code_list

		RAW_TYPE=`grep "yz${PRO_CATG}yz" $TMP_DIR/code_list | awk '{print $4}'`

		if [ Q$RAW_TYPE = "Q" ]
		then
			echo "*** WARNING: $FILE: unknown PRO_CATG $PRO_CATG. Skipped."
			continue
		fi

		CODE=`grep "yz${PRO_CATG}yz" $TMP_DIR/code_list | grep $RAW_TYPE | awk '{print $2}'`
		CASE=`grep "^CASE" $CONFIG | grep "[[:space:]]${RAW_TYPE}[[:space:]]" | awk '{print $3}'`
	
		PARSTRING=""
		PARSTRING=`grep "^PARSTRING" $CONFIG | grep "[[:space:]]${CASE}[[:space:]]" | sed "s/&&$//" | sed "s/^.*&&//"`

		if [ "Q$PARSTRING" != "Q" ]
		then
			PAR_STRING=`eval "$TMP_DIR/parser_spec $FILE | $PARSTRING"`
		else
			PAR_STRING="NONE"
		fi

# ==============================================================================
# 3.3 Create USERSCINAME; check for maximal length 68 chars
# ==============================================================================

		LENGTH_CHECK=`echo "${MCAL_CODE}_${CODE}_${OBS_ID}_${DATETIME}_${PAR_STRING}.${SUFFIX}" | awk '{print length}'`
		if [ $LENGTH_CHECK -gt 68 ]
		then
			echo "***ERROR: ${MCAL_CODE}_${CODE}_${OBS_ID}_${DATETIME}_${PAR_STRING}.${SUFFIX} is longer than 68 chars."
			echo "            You will cause troubles downstream with fitsort and the database. Shorten the name definition and try again."
			echo "Hit return to continue:"
			read input
			exit -1
		fi
		echo "$FILE ${MCAL_CODE}_${CODE}_${OBS_ID}_${DATETIME}_${PAR_STRING}.${SUFFIX} $PRO_CATG" >> rn_files 
	done
fi

# ==============================================================================
# 4. Versioning for CALIB, final executable rn_files for SCIENCE
# 4.1 Finish SCIENCE
# ==============================================================================

if [ $MODE = "SCIENCE" ] || [ $MODE = "GEN" ]
then	
	echo ""
	echo " 2. Versioning: no versioning needed for MODE = ${MODE}."
	cat rn_files | awk '{print $1,$2}' | sed "s/^.*/mv &/" > rn_files1
	mv rn_files1 rn_files

# ==============================================================================
# 4.2 Multiplicity check
# ==============================================================================

	if [ "QCHECK_YN" != "QNO" ]
	then
		NUMBER_FILES=`cat rn_files | awk '{print $2}' | wc -l`
		NUMBER_NAMES=`cat rn_files | awk '{print $3}' | wc -l`

		if [ $NUMBER_FILES != $NUMBER_NAMES ]
		then
			echo "*** WARNING: Number of names ($NUMBER_NAMES) is less than number of files ($NUMBER_FILES). Danger of overwriting."
		fi
	fi

# execute optional plugin

	if [ "Q$SPECIAL_PLUGIN" != "QNONE" ]
	then
		eval "$DFO_BIN_DIR/$SPECIAL_PLUGIN"
	fi

	if [ $MODE = "SCIENCE" ]
	then
		DFO_STATUS="sci_Renamed"
		set_DFO_STATUS
	fi

	rm -f $DFO_CONFIG_DIR/fitsreport_renameProducts.cfg

	chmod u+x rn_files
	echo ""
	echo "... done. Check out rn_files and execute."
	exit 0
fi

# ==============================================================================
# 4.2 Versioning for CALIB
# NOTE: Versioning works on full set of data, as opposed to file renaming which works
# file by file.
# ==============================================================================

if [ ! -s rn_files ]
then
	echo " No files renamed. Exit."
	exit
fi

echo " 2. Versioning ..."
echo ""
rm -f $TMP_DIR/catg_version_list

# prepare rn_files to be more robust for PRO_CATG matches
cat rn_files | awk '{print $1,$2,"yz"$3"yz"}' > rn_files10

# all CODES with VERSIONING=YYES
grep CODE $CONFIG | grep -v "^#" | grep YYES | awk '{print $3}' > $TMP_DIR/catg_version_list
if [ -s $TMP_DIR/catg_version_list ]
then
	for CV in `cat $TMP_DIR/catg_version_list`
	do
		rm -f $TMP_DIR/instance_list
		grep "yz${CV}yz" rn_files10 | awk '{print $2}' | sort -u > $TMP_DIR/instance_list
		if [ ! -s $TMP_DIR/instance_list ]
		then
			continue
		fi

		for INST in `cat $TMP_DIR/instance_list`
		do
			grep $INST rn_files > $TMP_DIR/version_list
			$TMP_DIR/counter >> rn_files1
		done
	done
fi

# all CODES with VERSIONING = NONO

grep "^CODE" $CONFIG | grep NONO | awk '{print $3}' > $TMP_DIR/catg_version_list
if [ -s $TMP_DIR/catg_version_list ]
then
	for CV in `cat $TMP_DIR/catg_version_list`
	do
		grep "yz${CV}yz" rn_files10 | sed "s/VERSION/A/" | awk '{print $1,$2}' | sed "s/^.*/mv &/" >> rn_files2
	done
fi

cat rn_files1 rn_files2 2>/dev/null | sort -k3 > rn_files 
chmod u+x rn_files

rm -f rn_files1 rn_files2 rn_files10

# ==============================================================================
# 5.3 Multiplicity check
# ==============================================================================

if [ "QCHECK_YN" != "QNO" ]
then
	NUMBER_FILES=`cat rn_files | awk '{print $2}' | wc -l`
	NUMBER_NAMES=`cat rn_files | awk '{print $3}' | wc -l`

	if [ $NUMBER_FILES != $NUMBER_NAMES ]
	then
		echo "*** WARNING: Number of names ($NUMBER_NAMES) is less than number of files ($NUMBER_FILES). Danger of overwriting."
	fi
fi

# execute optional plugin
if [ "Q$SPECIAL_PLUGIN" != "QNONE" ]
then
	eval "$DFO_BIN_DIR/$SPECIAL_PLUGIN"
fi

# ==============================================================================
# 5.4 End
# ==============================================================================

DFO_STATUS="cal_Renamed"
set_DFO_STATUS

rm -f $DFO_CONFIG_DIR/fitsreport_renameProducts.cfg

echo "... done. Check out rn_files and execute."

exit 0
