#!/bin/bash

set -eu

save_directory=""
saveset_pattern=""
pathname=""
nonrecursive=""
directory=False
file=False

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

    echo "Usage: $0"
    echo "    --save-directory /backshift-production/save-directory"
    echo "    --saveset-pattern '^.*hostname.*subset.*$'"
    echo "    --pathname /f/n"
    echo "    --nonrecursive"
    echo "    --directory"
    echo "    --file"
    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)'
    echo
    echo "Note that --file implies --nonrecursive"

    exit "$retval"
}

while [ "$#" -ge 1 ]
do
    case "$1" in
        --save-directory)
            save_directory="$2"
            shift
            ;;
        --saveset-pattern)
            saveset_pattern="$2"
            shift
            ;;
        --pathname)
            pathname="$2"
            shift
            ;;
        --nonrecursive)
            nonrecursive="$1"
            ;;
        --directory)
            directory=True
            ;;
        --file)
            file=True
            ;;
        --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 "$pathname" in
    "")
        echo "$0: --pathname is a required option" 1>&2
        preflight_check_ok=False
        ;;
    /*)
        # Good, it starts with a slash
        ;;
    *)
        echo "$0: --pathname must specify an absolute path" 1>&2
        preflight_check_ok=False
        ;;
esac

case "$directory-$file" in
    True-True|False-False)
        preflight_check_ok=False
        echo "$0: You must specify exactly one of --directory or --file, to indicate the type of file you wish to extract" 1>&2
        ;;
    True-False)
        # This is a directory extraction
        absolute_directory="$pathname"
        # shellcheck disable=SC2001
        pathname="$pathname"
        ;;
    False-True)
        # This is a file extraction
        absolute_directory=$(dirname "$pathname")
        # shellcheck disable=SC2001
        nonrecursive="--nonrecursive"
        ;;
    *)
        echo "$0: internal error: \$directory and/or \$file have strange values: $directory and $file" 1>&2
        exit 1
        ;;
esac

# shellcheck disable=SC2001
relative_directory="$(echo "$absolute_directory" | sed 's#^/##')"

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

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"
    # shellcheck disable=SC2086
    # We intentionally do not quote $nonrecursive - it sometimes needs to expand to nothing, not an empty string.
    backshift \
            --save-directory "$save_directory" \
            --backup-id "$backup_id" \
            --produce-tar \
            --starting-directory "$absolute_directory" \
            $nonrecursive \
        | tar xvfp - "$relative_directory" \
        || true
    )
done

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