#!/bin/bash

bn="`basename "$0"`"
if echo "$bn" | grep -q -- "-gui$"; then
  gui=1
fi

if test -z "$1"; then
  echo -en "\
Usage:  $bn URL [CONTENT-TYPE-OVERRIDE]

Examples:
  $bn aesgcm://files.xmpp.example.org/7/r/7rEFTd6cxUI#473360e0ad24889959858995\\
4c8ebfe1444ec1b2d503c6986659af2c94fafe945f72c1e8486a5acfedb8a0f8
  $bn file:///home/me/Downloads/7rEFTd6cxUI image/jpeg

In abscence of the URL fragment, like in the last example, $bn prompts for the
IV+key string interactively.

If the command is called with a name ending in -gui, it:
  1. tries to use a dialog window as the prompt;
  2. tries to return 0 when failing for non-syntax reasons, for more sensible
     integration with xdg-open.
" >&2
  exit 1
fi

if test "`echo "$1" | cut -d: -f1 -s`" = "aesgcm"; then
  url="https:`echo "$1" | cut -d: -f2 -s`"
else
  url="$1"
fi
type_override="$2"
ivkey="`echo "$url" | cut -d# -f2 -s`"
if test -z "$ivkey"; then
  prompt="Enter IV and key, concatenated, in hex"
  if test "$gui" != 1; then
    read -sp "$prompt (won't be echoed): " ivkey || exit 1
    echo ""
  elif which zenity > /dev/null; then
    ivkey="`zenity --entry --width=400 --hide-text --title="unaesgcm" \
      --text="Decrypting $url\n\n$prompt:" --entry-text="\
0123456789abcdef01234567\
89abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234567"`" || exit 0
  fi
fi
url="`echo "$url" | cut -d# -f1`"

get_filename_and_type()
{
  curl \
    --location --url "$url" \
    --range 0-0 --silent --show-error \
    --remote-name --remote-header-name \
    --write-out '%{filename_effective}\n%{content_type}\n'
}

download_decrypt_and_open()
{
  local fn="$1"
  local type="$2"
  if test -z "$fn"; then
    fn="$(mktemp -p.)" || (echo "fatal filename failure" >&2; exit 1)
  fi
  if test -n "$type_override"; then
    echo "overriding content type '$type' with '$type_override'" >&2
    type="$type_override"
  elif test -z "$type"; then
    echo "unknown content type (and none provided via command line)" >&2
  fi
  curl --location --url "$url" | "`dirname "$0"`/unaesgcm" /dev/stdin "$fn" "$ivkey" &&
  (
    if test -n "$type" && which gtk-launch > /dev/null &&
      application="`xdg-mime query default "$type"`"; then
      gtk-launch "$application" "$fn"
    else
      xdg-open "$fn"
    fi
  )
}

dir="$(mktemp -d)" &&
cd "$dir" &&
filename_and_type="$(get_filename_and_type)" &&
echo "$filename_and_type" |
(
  read -r fn
  rm "$fn"
  read -r type
  download_decrypt_and_open "$fn" "$type"
)

res=$?
test "$gui" = 1 && exit 0
exit "$res"
