#!/bin/bash

set -eu
set -o pipefail

save_directory=""
dry_run=false
warning=true

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

    echo "Usage: $0 --save-directory /backshift/save-directory --dry-run --skip-warning" 1>&2
    echo
    echo "Finds duplicate metadata files and hardlinks them - the goal being to"
    echo "reduce disk space requirements."
    echo
    echo "Do -not- run this during a backup.  Strange things can happen if you do."

    exit "$retval"
}

while [ "$#" -ge 1 ]
do
    case "$1" in
        --save-directory)
            save_directory="$2"
            shift
            ;;
        --dry-run)
            dry_run=true
            ;;
        --skip-warning)
            warning=false
            ;;
        -h|--help)
            usage 0
            ;;
        *)
            echo "$0: unrecognized option: $1" 1>&2
            usage 1
            ;;
    esac
    shift
done

case "$save_directory" in
    "")
        echo "$0: --save-directory is a required option"
        usage 1
        ;;
esac

if ! cd "$save_directory"
then
    echo "$0: cd to $save_directory failed" 1>&2
    exit 1
fi

if ! cd "files"
then
    echo "$0: cd to $save_directory/files failed" 1>&2
    exit 1
fi

case "$warning" in
    true)
        echo "Warning: This program should not be used during a backup or expire.  Data loss could result!" 1>&2
        while true
        do
            echo 'Continue (y/N)?'
            read -r line
            first_character=$(echo "$line" | sed 's/^\(.\).*$/\1/' | tr '[:upper:]' '[:lower:]')
            case "$first_character" in
                y)
                    break
                    ;;
                n|"")
                    echo Exiting.
                    exit 0
                    ;;
                *)
                    echo "Please enter y or n"
                    continue
                    ;;
            esac
        done
        ;;
    false)
        ;;
    *)
        echo "$0: internal error: \$warning has a strange value: $warning" 1>&2
        exit 1
        ;;
esac

# A dry run require too much RAM to complete correctly, even on a system with 32G of physmem and 33 G of swap space.
# I had to manually recompile with rdfind's internal maxdepth variable set to 500 to get that far.
# rdfind -dryrun "$dry_run" -makehardlinks true .

case "$dry_run" in
    true)
        fdupes -r .
        ;;
    false)
        fdupes -rL .
        ;;
    *)
        echo "$0: internal error: \$dry_run has a strange value: $dry_run" 1>&2
        exit 1
        ;;
esac