#!/bin/bash

set -eu

save_directory=""
saveset_pattern=""
filename=""

function usage
{
    retval="$1"
    case "$retval" in
        0)
            ;;
        *)
            exec 1>&2
            ;;
    esac

    echo "Usage: $0 --save-directory /backshift-production/save-directory --saveset-pattern '^.*hostname.*subset.*$' --filename /f/n"
    echo
    echo 'Extract all versions of a file in the save directory, for a given saveset pattern'
    # shellcheck disable=SC2016
    echo 'Extracts all files to ./extracts/$backup_id/$directory/$(basename $filename)'

    exit "$retval"
}

while [ "$#" -ge 1 ]
do
    case "$1" in
        --save-directory)
            save_directory="$2"
            shift
            ;;
        --saveset-pattern)
            saveset_pattern="$2"
            shift
            ;;
        --filename)
            filename="$2"
            shift
            ;;
        --help|-h)
            usage 0
            ;;
        *)
            echo "$0: unrecognized option: $1" 1>&2
            usage 1
            ;;
    esac
    shift
done

preflight_check_ok=True

case "$save_directory" in
    "")
        echo "$0: --save-directory is a required option" 1>&2
        preflight_check_ok=False
        ;;
esac

case "$saveset_pattern" in
    "")
        echo "$0: --saveset-pattern is a required option" 1>&2
        preflight_check_ok=False
        ;;
esac

case "$filename" in
    "")
        echo "$0: --filename is a required option" 1>&2
        preflight_check_ok=False
        ;;
    /*)
        # Good, it starts with a slash
        ;;
    *)
        echo "$0: --filename must specify an absolute path" 1>&2
        preflight_check_ok=False
        ;;
esac

case "$preflight_check_ok" in
    True)
        ;;
    False)
        echo "$0: One or more items in preflight check failed" 1>&2
        exit 1
        ;;
    *)
        echo "$0: Internal error: \$preflight_check_ok has a strange value: $preflight_check_ok" 1>&2
        exit 1
        ;;
esac

absolute_directory=$(dirname "$filename")

# Make $filename relative
# shellcheck disable=SC2001
filename=$(echo "$filename" | sed 's#^/##')

# And get the directory that contains it
# relative_directory=$(dirname "$filename")

function backup_ids
{
    # Note that this will only list completed savesets.
    backshift --save-directory "$save_directory" --list-backups | grep -E "$saveset_pattern" | awk '$4 != "None" { print $1 }'
}

mkdir -p extracts
cd extracts

echo "Obtaining list of backup ids"

for backup_id in $(backup_ids)
do
    export backup_id
    echo Checking "$backup_id"
    (
    set -eu
    mkdir -p "$backup_id"
    cd "$backup_id"
    backshift \
            --save-directory "$save_directory" \
            --backup-id "$backup_id" \
            --produce-tar \
            --starting-directory "$absolute_directory" \
            --nonrecursive \
        | tar xvfp - "$filename" \
        || true
    )
done

echo
echo 'Now consider running something like:'
echo 'find extracts -type f -print0 | equivs3e -v -0 --one-per-duplicate'
