#!/bin/sh

# File: refdb-backup

# Author: David Nebauer

# History: 2004-11-28 Created

# Purpose: Restores references, notes and styles

# Parameter: 1 - backup archive


# VARIABLES
references_backup="references"  # base of references backup file name
notes_backup="xnotes.xml"  # notes backup file name
styles_directory="styles"  # name of styles directory (intra-archive)
start_dir=`pwd`  # directory in which utility is run
refdba="refdba"  # refdba command
refdbc="refdbc"  # refdbc command
archive=$1  # name of backup archive
parameters="[-u USER] [-w PWD] <backup_archive>"  # cmd-line options

# PROCEDURES

# Report success of operation
#   params: 1 - exit status
#   return: nil
report () {
	if [ $1 -eq 0 ] ; then echo "OK." ; else echo "Failed." ; fi
}
# Report failure and abort
#   params: 1 - exit message
#           2 - success indicator ( 'succeeded'|* )
#   retuns: nil
endScript () {
	# attempt to change back to initial directory
	cd ${start_dir} || \
		echo "Error: Unable to cd to start dir '${start_dir}'."
	# attempt to delete temporary files
	[ -d ${tempdir} ] && rm -fr ${tempdir} || \
		echo "Error: Unable to delete temporary directory '${tempdir}'."
	# provide feedback regarding success of backup
	echo ; echo "$1"
	echo ; echo "refdb restore $2."
	echo "`basename $0` is finished."
	# provide exit status to shell
	if [ "$2" = "succeeded" ] ; then exit 0 ; else exit 1 ; fi
}
# Show usage
#   params: nil
#   return: nil
displayUsage () {
	echo "`basename $0`: Restores RefDb data from backup."
	echo
	echo "Restores references, notes and styles from backup archive."
	echo
	echo "Usage: `basename $0` ${parameters}"
	echo
	echo "Must be archive created by 'refdb-backup' utility."
	echo
	echo "Options: -u USER   = username for RefDB clients ('refdba'|'refdbc')"
	echo "         -w PWD    = password for RefDB clients ('refdba'|'refdbc')"
	echo "Note: RefDB clients can be configured for automatic access."
	echo "      If this is so, username and password are not required."
}
# Determine name of reference database backup file
#   params: 1 - archive name
#           2 - database name
#           3 - backup file basename
#   return: filename ('db_DBNAME/BACKUPFILE.EXTENSION')
get_filename () {
	archive=$1
	db=$2
	base=$3
	filelist=`tar -tzf $1 | grep -v "/$" | grep "^db_"`
	[ `echo "${filelist}" | grep "^db_${db}/${references_backup}.xml"` ] \
		&& extension="xml"
	[ `echo "${filelist}" | grep "^db_${db}/${references_backup}.ris"` ] \
		&& extension="ris"
	echo "db_${db}/${references_backup}.${extension}"
}
# Determines format of backup reference file
#   params: 1 - backup filepath
#   return: format ('ris'|'risx')
get_format () {
	filepath=$1
	filename=${filepath##*/}  # strip path
	extension=${filename##*.}  # strip basename
	case ${extension} in
		ris ) echo "ris";;
		xml ) echo "risx";;
		*   ) echo "ERROR";;
	esac
}


# MAIN

# Read the command line options
while getopts ":hu:w:" opt ; do
	case ${opt} in
		h  ) displayUsage && exit 0;;
		u  ) refdba="${refdba} -u \"${OPTARG}\""
		     refdbc="${refdbc} -u \"${OPTARG}\"";;
		w  ) refdba="${refdba} -w \"${OPTARG}\""
		     refdbc="${refdbc} -w \"${OPTARG}\"";;
		\? ) echo "Error: Invalid flag '${OPTARG}' detected"
		     echo "Usage: `basename $0` ${parameters}"
		     echo "Try '`basename $0` -h' for help"
			 printf "\a"
			 exit 1;;
		\: ) echo "Error: No argument supplied for flag '${OPTARG}'"
		     echo "Usage: `basename $0` ${parameters}"
		     echo "Try '`basename $0` -h' for help"
			 printf "\a"
			 exit 1;;
	esac
done
shift $(( ${OPTIND} - 1 ))  # not really needed, but...


# Check for valid arguments
# - run tests on archive
	# - first, convert relative to absolute filepath
[ `echo ${archive} | grep -v "^\/"` ] && archive="${start_dir}/${archive}"
	# - must exist and be readable
[ -r ${archive} ] || \
	endScript "Cannot read backup archive '${archive}'." "failed"
	# - must be valid archive (this test is a bit crude - just list
	#   archive contents and check exit status)
tar -tzf ${archive} >/dev/null 2>&1 || \
	endScript "'${archive}' is not a valid archive." "failed"

# Test for RefDB access
${refdba} -C listdb >/dev/null 2>&1 || \
	endScript "Error: Unable to access RefDB using client 'refdba'." "failed"
${refdbc} -C listdb >/dev/null 2>&1 || \
	endScript "Error: Unable to access RefDB using client 'refdbc'." "failed"

# Will use temporary directory for working
# - ensure deletion on exit and change to working directory
tempdir_base="`basename $0`.XXXXXX"
tempdir=`mktemp -dq ${tempdir_base}` \
	|| endScript "Error: Unable to create temporary directory." "failed"
[ `echo ${tempdir} | grep -v "^\/"` ] && tempdir="${start_dir}/${tempdir}"
trap "rm -fr ${tempdir}" 0 1 2 3 5 15  # delete on exit
cd ${tempdir} || \
	endScript "Error: Unable to cd to temporary directory '${tempdir}'." \
	"failed"

# Informational message
echo "`basename $0` is running..." ; echo

# Cycle through databases in turn and restore references and notes
for dbdir in `tar -tzf ${archive} | grep "/$"` ; do
	# get db name
	if [ ${dbdir} != "styles/" ] ; then
		db=${dbdir##db_}  # remove prefix
		db=${db%%/}  # remove trailing slash
		echo "Restoring database: ${db}"
		# restore references
		reffile=`get_filename ${archive} ${db} ${references_backup}`
		echo "  Restore references"
		# - extract file
		echo -n "    Extracting temporary file ... "
		tar -xzf ${archive} ${reffile} >/dev/null 2>&1
		report $?
		# - create database
		echo -n "    Create database ... "
		refdba -C createdb ${db} >/dev/null 2>&1
		report $?
		# - add references
		echo -n "    Adding references ... "
		format=`get_format ${reffile}`
		refdbc -C addref -d ${db} -t ${format} ${reffile} >/dev/null 2>&1
		report $?
		# restore notes
		notefile="db_${db}/${notes_backup}"
		echo "  Restore notes"
		# - extract file
		echo -n "    Extracting temporary file ... "
		tar -xzf ${archive} ${notefile} >/dev/null 2>&1
		report $?
		# - add notes
		echo -n "    Adding notes ... "
		refdbc -C addnote -d ${db} ${notefile} >/dev/null 2>&1
		report $?
	fi
done

# Restore styles
echo "Restoring styles"
for stylefile in `tar -tzf ${archive} | grep "^styles/[[:print:]]\+"` ; do
	# extract style file
	echo -n "  Extracting style: "
	tar -xzf ${archive} ${stylefile} >/dev/null 2>&1
	if [ $? -eq 0 ] ; then
		# extract style name
		stylename=`grep "^[[:print:]]*<STYLENAME>" ${stylefile}`
		stylename=${stylename#[[:print:]]*<STYLENAME>}
		stylename=${stylename%<\/STYLENAME>}
		echo ${stylename}
		# add style
		echo -n "    Adding style ... "
		refdba -C addstyle ${stylefile} >/dev/null 2>&1
		report $?
	else
		report 1
	fi
done

# Finished
endScript "Restore finished." "succeeded"
