#!/bin/sh

# for shellrc:
# alias encrypt-kasse="gpgfile.sh -k 52BE43BA -k 7A97EAD5 -k 8AFDAD2D -e /path/to/kassenbuch.odt"
# alias decrypt-kasse="gpgfile.sh -d -e /path/to/kassenbuch.odt.gpg"
# alias encrypt-documents="gpgfile.sh -k 7A97EAD5 -e /path/to/documents"
# alias decrypt-documents"gpgfile.sh -d -e /path/to/documents.tar.gpg"

### functions
usage() {
  echo "usage: $(basename $0) <options> <files/dirs>"
  echo "options:"
  echo "    -k <key_id>  key id (can be supplied multiple times)"
  echo "    -e           encrypt files or directories (requires -k)"
  echo "    -d           decrypt files or directories"
  echo "note: directories will be wrapped in tar(1)"
  exit 2
}

### main program

# parse arguments
while getopts 'k:edh' arg
do
    case ${arg} in
        k) keylist="$keylist -r $OPTARG" ;;
        e) encrypt=1 ;;
        d) encrypt=0 ;;
        h) usage ;;
        ?) usage ;;
    esac
done
# shift parsed arguments out of the way $1 starts now with files/dirs
shift $(($OPTIND - 1))

# print usage, if no file/dir argument is provided
[ -z "$1" ] \
    && echo "ERROR: No files/dirs argument provided." \
    && usage

# print usage, if no option argument was provided
[ "$OPTIND" == "1" ] \
    && echo "ERROR: No option provided (needs -d, or -e and -k)" \
    && usage

### handle encryption (set by -e)
if [ "$encrypt" -eq "1" ]
then

    # no key? 
    [ -z "$keylist" ] \
        && echo "ERROR: Encryption mode (-e) needs a key (-k), which was not provided." \
        && exit 1

    # loop at provided files
    for item in "$@"
    do
        # Work in a subshell so dir changes won't be persistent.
        # Due to this, we "return" instead of "continue".
        # This is needed because we don't want to include the
        # basedir hierarchy in tar files.
        (

        # change working directory
        cd "$(dirname "$item")"
        item="$(basename "$item")"

        # don't handle non existant files
        readlink -f "$item" > /dev/null 2>&1 \
            || { echo "$item: skipped: file not found" \
                 && return; }

        # don't re-encrypt gpg files
        [ "${item##*.}" == "gpg" ] \
            && echo "$item: skipped: already gpg encrypted" \
            && return

        # handle directory: tar + gpg, then remove original dir + tar
        [ -d "$item" ] \
            && echo "$item -> $item.tar" \
            && tar -cf "$item.tar" "$item" \
            && rm -rf "$item" \
            && item="$item.tar"
            # no return: fallthrough to next handler

        # handle files: gpg, then remove original file
        [ -f "$item" ] \
            && echo "$item -> $item.gpg" \
            && gpg -q -e $keylist -o "$item.gpg" "$item" \
            && rm -f "$item"

        ) # exit subshell
    done
fi

### handle decryption (set by -d)
if [ $encrypt -eq 0 ]
then
    for item in "$@"
    do
        # Work in a subshell so dir changes won't be persistent.
        # Due to this, we "return" instead of "continue".
        # This is needed because we don't want to include the
        # basedir hierarchy in tar files.
        (

        # change working directory
        cd "$(dirname "$item")"
        item="$(basename "$item")"

        # don't handle non existant files
        readlink -f "$item" > /dev/null 2>&1 \
            || { echo "skipping: $item (reason: file not found)" \
                 && return; }

        # don't handle files that are not gpg encrypted
        [ "${item##*.}" != "gpg" ] \
            && echo "skipping: $item (reason: not a gpg file)" \
            && return

        # handle file: decrypt with gpg + delete encrypted version
        [ "${item##*.}" == "gpg" ] \
            && echo "$item -> ${item%.*}" \
            && gpg -q -d -o "${item%.*}" "$item" \
            && rm -f "$item" \
            && item="${item%.*}"
            # no return: fallthrough to next handler

        # handle tar: if file ends in tar after decryption, untar it and delete the tar.
        [ "${item##*.}" == "tar" ] \
            && echo "$item -> ${item%.*}" \
            && tar xf "$item" \
            && rm -f "$item"

        ) # exit subshell
    done
fi
