#!/bin/sh

export LANG="UTF-16"

# v0.6 add finish time prediction
# v0.5 change + bsd tar
# v0.4 read with 4m buffer, write with 128k
# v0.3 added mbuffer to restore
# v0.2 merge restore/backup script and add parameter handling
# v0.1 initial version

### CONFIG ###

_key="/etc/keyfile"
_dev="/dev/nsa0"
_buffer="8G"
_tapeln="10320" # full tape read/write time in seconds

### FUNCTIONS ###

V=0.6

usage() {
    printf '%s%s\n%s\n%s\n%s\n\n' \
        "$0" ": <mode> <directory>" \
        "   -b             backup mode" \
        "   -r             restore mode" \
        "   <directory>    directory to backup or restore to"
        exit 2
}

_src="$(readlink -f "$2")"
[ -z $_src ] && printf 'File or Directory does not exist: %s\n\n' "$1" && usage

dates() {
    printf 'Start: %s\nEnd:   %s (predicted)\n' "$(date)" "$(date -r $(($(date +%s)+$_tapeln)))"
}

backup() {
    printf 'Calculating...\n'
    printf 'Backing up %s with a total size of %s\n' "$_src" "$(du -hs $_src | awk '{ print $1 }')"
    dates
    tar -b 2048 -cf - "$_src" \
        | zstd -T0 \
        | openssl enc -e -pbkdf2 -aes256 -pass file:$_key \
        | mbuffer -v 1 -t -m $_buffer -P 90 -s 4096k \
        | dd of=$_dev ibs=4096k obs=128k
        printf 'End: %s\n' "$(date)"
}

restore() {
    printf 'Restoring data to %s (logging to restore.log)\n' "$_src"
    dates | tee restore.log
    dd if=$_dev ibs=128k obs=4096k \
        | openssl enc -d -pbkdf2 -aes256 -pass file:$_key \
        | zstd -T0 -d \
        | mbuffer -v 1 -t -m $_buffer -s 4096k \
        | tar -C "$_src" -b 2048 -xvf - >> restore.log 2>&1
    printf 'End: %s\n' "$(date)" | tee restore.log
}

list() {
    printf 'Reading Index\n'
    printf 'Start: %s\n Predicted End: %s\n'\
        "$(date)" "date -r $(($(date +%s)+$_tapeln))"

    dd if=$_dev ibs=128k obs=4096k \
        | openssl enc -d -pbkdf2 -aes256 -pass file:$_key \
        | gtar --zstd -tf /dev/stdin
    date
}

### MAIN PROGRAM ###

blogo() {
printf '%s%s%s\n\n' \
'
  ______                    ____             __
 /_  __/___ _____  ___     / __ )____ ______/ /____  ______
  / / / __ `/ __ \/ _ \   / __  / __ `/ ___/ //_/ / / / __ \
 / / / /_/ / /_/ /  __/  / /_/ / /_/ / /__/ ,< / /_/ / /_/ /
/_/  \__,_/ .___/\___/  /_____/\__,_/\___/_/|_|\__,_/ .___/
         /_/ CODEVOID BACKUP TOOL v'"$V"'             /_/
'
}

rlogo() {
printf '%s%s\n\n' \
'
  ______                    ____            __
 /_  __/___ _____  ___     / __ \___  _____/ /_____  ________
  / / / __ `/ __ \/ _ \   / /_/ / _ \/ ___/ __/ __ \/ ___/ _ \
 / / / /_/ / /_/ /  __/  / _, _/  __(__  ) /_/ /_/ / /  /  __/
/_/  \__,_/ .___/\___/  /_/ |_|\___/____/\__/\____/_/   \___/
         /_/ CODEVOID BACKUP TOOL v'"$V"
}

case $1 in
    -b) blogo;
        backup;
        ;;
    -r) rlogo;
        restore;
        ;;
    *) usage;
        ;;
esac
