#!/bin/sh

TARSNAP_CMD=/usr/local/bin/tarsnap

path2name() {
    res=$(echo "$1" | sed -E -e 's,/+,/,g' -e 's,/$|^/,,g' -e 's,/,-,g')
    if [ -z "$res" ]; then
        res='ROOT'
    fi
    echo $res
}

something_wrong=0

# make the appropriately named backup
create_backup()
{
    path=$1
    type=$2

    case "$type" in
        daily)
        now=$(date +"$type-%Y-%m-%d")
        ;;
        weekly)
        now=$(date +"$type-%Y-%U")
        ;;
        monthly)
        now=$(date +"$type-%Y-%m")
        ;;
        yearly)
        now=$(date +"$type-%Y")
        ;;
        *)
        echo "unknown backup type: $type"
        exit 1
    esac

    fullname="$(path2name "$path")-$now"
    # look for an existing backup with this name
    if $TARSNAP_CMD --list-archives | grep -q "^${fullname}$"; then
        echo "* backup $fullname already exists, skipping..."
    else
        echo "  * making backup: $fullname"
        $TARSNAP_CMD -c -f "$fullname" "$path" || something_wrong=1
    fi
}

# delete the named backup
delete_backup()
{
    backup=$1
    echo "  * deleting old backup: $backup"
    $TARSNAP_CMD -d -f "$backup"
}

# make a $type backup of path, cleaning up old ones
do_path()
{
    path=$1
    keep=$2
    type=$3

    name="$(path2name "$path")"

    # create the regex matching the type of backup we're currently working on
    case "$type" in
        daily)
        # $name-daily-2009-01-01
        regex="^$name-$type-[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$"
        ;;
        weekly)
        # weekly-2009-01
        regex="^$name-$type-[0-9][0-9][0-9][0-9]-[0-9][0-9]$"
        ;;
        monthly)
        # monthly-2009-01
        regex="^$name-$type-[0-9][0-9][0-9][0-9]-[0-9][0-9]$"
        ;;
        yearly)
        # yearly-2009
        regex="^$name-$type-[0-9][0-9][0-9][0-9]$"
        ;;
        *)
        echo "unknown backup type: $type"
        exit 1
    esac

    create_backup "$path" "$type"

    # get a list of all of the backups of this type sorted alpha, which
    # effectively is increasing date/time
    backups=$($TARSNAP_CMD --list-archives | grep "$regex" | sort)
    count=$(echo "$backups" | wc -l)
    if [ "$count" -ge 0 ]; then
        # how many items should we delete
        delete=$((count - keep))
        count=0
        # walk through the backups, deleting them until we've trimmed deleted
        for backup in $backups; do
            if [ $count -ge $delete ]; then
                break
            fi
            delete_backup "$backup"
            count=$((count + 1))
        done
    fi
}

# make $type backups, for paths, cleaning up old ones
do_backups()
{
    paths=$1
    keep=$2
    type=$3

    echo ""
    echo "Doing tarsnap $type backups:"
    for path in $paths; do
        do_path "$path" "$keep" "$type"
    done
    if [ -n "$something_wrong" ]; then
        exit 3
    fi
}

if [ $# -ne 3 ]; then
    echo "Usage: $0 \"<paths>\" <keep> daily|weekly|monthly|yearly"
    exit 2
fi

# FreeBSD 12.0 adds an anticongestion function
if [ -n "$anticongestion_sleeptime" ]; then
    anticongestion
fi

do_backups "$1" "$2" "$3"
