#!/bin/bash

#######################################
# BCKROOT=   # Backup root
# BCKNAME=   # Backup name
# BCKSRC=    # Source dir
# BCKDIR=    # Backupdir
# KEEPDAYS=  # Keep days
# BCKOPTS="" # Rsync options
# BCKBATCH=  # Make backup batch (1)
#######################################

function dircheck() {

    #exit if backup root doesn't exist
    [ -d $BCKROOT ] || exit 21
    #exit if backup name doesn't exist
    [ "x$BCKNAME" == "x" ] && exit 27
    #exit if backup dir is /
    [ "x$BCKDIR" == "x" ] && exit 23
    #exit if source doesn't exist
    [ -z $BCKSRC ] || exit 25
    [ -d $BCKSRC ] || exit 25

    #make dirs
    [ -d $BCKDIR ] || mkdir $BCKDIR
    [ -d $BCKDIR/daily ] || mkdir $BCKDIR/daily
    [ -d $BCKDIR/weekly ] || mkdir $BCKDIR/weekly
    [ -d $BCKDIR/temp ] || mkdir $BCKDIR/temp

    #backup status
    [ -d $BCKROOT/.status ] || mkdir $BCKROOT/.status
    [ -d $BCKROOT/.status/$BCKNAME ] || mkdir $BCKROOT/.status/$BCKNAME

    if [ $BCKBATCH -eq 1 ]; then
	[ -d $BCKROOT/.batch ] || mkdir $BCKROOT/.batch
	[ -d $BCKROOT/.batch/$BCKNAME ] || mkdir $BCKROOT/.batch/$BCKNAME
    fi

}

function makebackup() {

    # check backup dirs
    dircheck

    DAY=`date +%u-%a`
    DAYY=`date +%u-%a -d "yesterday"`
    TS=`date +%Y-%m-%d`

    [ -d $BCKDIR/daily/$DAY ] || mkdir $BCKDIR/daily/$DAY
    [ -d $BCKDIR/daily/$DAYY ] || mkdir $BCKDIR/daily/$DAYY

    # get last successful backup
    if [ -L $BCKDIR/current ]; then

	blast=`readlink $BCKDIR/current`

	if [ "x$blast" == "xdaily/$DAY" ]; then
	    blast="daily/$DAYY"
	    echo -n "- A backup was already done today."
	    if [ $BCKBATCH -eq 1 ]; then
		echo " Exiting."
		exit 47
	    else
		echo " Re-syncing."
	    fi
	fi
    else
	blast="daily/$DAYY"
    fi

    bsrc=$BCKSRC
    bdst=$BCKDIR/daily/$DAY

    WRITEBATCH=""
    if [ $BCKBATCH -eq 1 ]; then
	bbatchtmp=$BCKDIR/temp/$TS.batch
	bbatch=$BCKROOT/.batch/$BCKNAME/$TS.batch

	WRITEBATCH="--write-batch=$bbatchtmp"

	if [ -f $bbatch ]; then
	    echo "- A backup batch file already exists for today. Exiting."
	    exit 49
	fi
    fi

    #sync with current
    rsync -a -r -q -E --delete --delete-excluded --force $WRITEBATCH --link-dest=../../$blast $BCKOPTS $bsrc/ $bdst/
    ERR=$?

    if [ $ERR -eq 0 -o $ERR -eq 24 ]; then

	touch $bdst

	# create current link
	[ -L $BCKDIR/current ] && rm $BCKDIR/current
	ln -s daily/$DAY $BCKDIR/current

	# create finished status file
	touch $BCKROOT/.status/$BCKNAME/$TS.finished

	if [ $BCKBATCH -eq 1 ]; then
	    # move batch
	    mv $bbatchtmp $bbatch
	    rm $bbatchtmp.sh
	    # delete old batch
	    find $BCKROOT/.batch/$BCKNAME/ -mtime +7 -type f -name "*.batch" -delete
	fi

    fi
}

function rotatebackup() {

    if [ "`date +%u`" == "7" ]; then

	# check backup dirs
	dircheck

	TS=`date +%Y-%m-%d`
	DAY=`date +%u-%a`

	[ -d $BCKDIR/daily/$DAY ] || exit 27

	# Run with low IO
	if [ -x /usr/bin/ionice ] && /usr/bin/ionice -c3 true 2>/dev/null; then
	    IONICE="/usr/bin/ionice -c3"
	fi

	# create weekly
	src=$BCKDIR/daily/$DAY
	dst=$BCKDIR/weekly/$TS
	[ -d $dst ] || mkdir $dst
	$IONICE cp -a -l $src/* $dst/

	$IONICE find $BCKDIR/weekly/ -mindepth 1 -maxdepth 1 -mtime +$KEEPDAYS -exec rm -r {} \;
    fi
}

function backuproute() {

    # The originating script name should be backup-* or rotate-*

    sn=${0##*/}
    func=${sn%%-*}

    echo -n "$func start: "
    date '+%T'

    [ "$func" == "backup" ] && makebackup
    [ "$func" == "rotate" ] && rotatebackup

    echo -n "$func end: "
    date '+%T'

}
