#!/bin/bash

#########################################
# Name: xfsync
#
# Summary: mirror one or more xfoce archives
#
# Description: 
# Uses rsync
#
# Invoke like this
# xfsync -f <file>
# xfsync -s <src> -d <dest> -k <keyfile>
#
# Author: kheadley
#
# Copyright MBARI 2014
#
#########################################

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

XFS_CONF="./xfsync.conf"

#################################
# Script variable initialization
#################################
VERBOSE="FALSE"

declare -a XFS_KEY_FILE
declare -a XFS_SRC
declare -a XFS_DEST

#################################
# name: printUsage
# description: print use message
# args: none
#################################
printUsage(){
    echo
    echo "usage: `basename $0` [options...]"
    echo "Options:"
    echo " -f <p>    : config file          [$XFS_CONF]"
    echo " -s <src>  : rsync source      e.g., user@src_host:path"
    echo " -d <dest> : rsync destination e.g., /home/user/mirrors"
    echo " -k <key>  : rsync key file    e.g., /home/user/rskeys/<src_host>-rskey"
    echo " -v        : verbose output       [$VERBOSE]"
    echo " -h        : print use message"
    echo ""
    echo
}

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

########################################
# 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 f:d:s:k:hv Option
	do
		vout "processing $Option[$OPTARG]"
        local len=0
		case $Option in
			f ) XFS_CONF=$OPTARG
			;;
            s )
                len=${#XFS_SRC[@]}
                XFS_SRC[$len]="$OPTARG"
            ;;
            d )
                len=${#XFS_DEST[@]}
                XFS_DEST[$len]=$OPTARG
            ;;
            k )
                len=${#XFS_KEY_FILE[@]}
                XFS_KEY_FILE[$len]=$OPTARG
            ;;
			v ) VERBOSE="TRUE"
			;;
			h) printUsage
				exit 0
			;;
			*) exit 0 # getopts outputs error message
			;;
		esac
	done
}


########################################
# name: xfs_validate
# description: validate sync options
# args:
#     args:       positional paramters (src,dest,keyfile)
#     returnCode: none
########################################
xfs_validate(){

vdest=$1
vkey=$2
vsrc="${3}"
local rval=0


# validate options
if [ ! "${vsrc}" ] || [ ! "${vdest}" ] || [ ! "${vkey}" ]
then
echo "missing ssh option XFS_SSH_KEY[${vkey}] XFS_SRC[${vsrc}] XFS_DEST[${vdest}]"
rval=1
fi

if [ ! -f "${vkey}" ]
then
echo "WARN: XFS_KEY_FILE not found [${vkey}]"
rval=0
fi

if [ ! -d "${vdest}" ]
then
echo "XFS_DEST not found [${vdest}]"
rval=1
fi

return $rval
}


##########################
# Script main entry point
##########################

# use simple arg processing
processCmdLine $*

# read options from config file
if [ -f "${XFS_CONF}" ]
then
    # pull in config file options
    source ${XFS_CONF}
fi

# check all parameters specified
# [number of src:dest:key should match]
if [ "${#XFS_SRC[@]}" -ne "${#XFS_DEST[@]}" ] || [ "${#XFS_SRC[@]}" -ne "${#XFS_KEY_FILE[@]}" ]
then
    exitError "parameter mismatch" -1
fi


let "i=0"
let "len=${#XFS_SRC[@]}"

while [ "${i}" -lt "$len" ]
do
    # test parameters for sync
    xfs_validate ${XFS_DEST[$i]} ${XFS_KEY_FILE[$i]} ${XFS_SRC[$i]}
    test=$?

    if [ $test -eq 0 ]
    then
        if  [ -f "${XFS_KEY_FILE[$i]}" ]
        then
            XFS_RSH="ssh -i ${XFS_KEY_FILE[$i]}"
        else
            XFS_RSH="ssh -l ${XFS_KEY_FILE[$i]}"
        fi
        vout ""
        vout "xfsync using"
        vout "XFS_SRC      :[${XFS_SRC[$i]}]"
        vout "XFS_DEST     :[${XFS_DEST[$i]}]"
        vout "XFS_KEY_FILE :[${XFS_KEY_FILE[$i]}]"
        vout "XFS_RSH      :[${XFS_RSH}]"

        # synchronize archive(s)
        start=`date +%s`
        rsync -aivz -e "${XFS_RSH}" ${XFS_SRC[$i]} ${XFS_DEST[$i]}
        rsync_ok="$?"
        end=`date +%s`
        let "elapsed=$end-$start"
        vout "sync time [${elapsed} (s)]"
    else
        echo ""
        echo "Invalid args:"
        echo "XFS_SRC      : [${XFS_SRC[$i]}]"
        echo "XFS_DEST     : [${XFS_DEST[$i]}]"
        echo "XFS_KEY_FILE : [${XFS_KEY_FILE[$i]}]"
        echo ""
    fi
    let "i=$i+1"
done
vout ""
