#!/bin/sh

set -eu

id_uuid=${1:-}
device_presentation=${2:-Encrypted disk}
pinentry_program=pinentry-gtk-2

if [ -z "$id_uuid" ]; then
  printf '%s\n' "udiskie-password: missing device UUID" >&2
  exit 1
fi

assuan_escape() {
  python3 -c 'import sys
value = sys.argv[1]
value = value.replace("%", "%25").replace("\n", "%0A").replace("\r", "%0D")
sys.stdout.write(value)' "$1"
}

pinentry_getpin() {
  title=$(assuan_escape "Unlock disk")
  prompt=$(assuan_escape "Passphrase:")
  description=$(assuan_escape "Enter passphrase for $device_presentation")
  response=$(
    {
      printf 'SETTITLE %s\n' "$title"
      printf 'SETPROMPT %s\n' "$prompt"
      printf 'SETDESC %s\n' "$description"
      printf 'GETPIN\n'
    } | "$pinentry_program"
  ) || return 1

  printf '%s\n' "$response" |
    python3 -c 'import sys
for line in sys.stdin.read().splitlines():
    if line.startswith("D "):
        value = line[2:].replace("%0A", "\n").replace("%0D", "\r")
        i = 0
        out = []
        while i < len(value):
            if value[i] == "%" and i + 2 < len(value):
                out.append(chr(int(value[i + 1:i + 3], 16)))
                i += 3
            else:
                out.append(value[i])
                i += 1
        sys.stdout.write("".join(out))
        break
else:
    sys.exit(1)'
}

pinentry_confirm_save() {
  title=$(assuan_escape "Save disk password")
  description=$(assuan_escape "Save the unlock passphrase for $device_presentation in GNOME Keyring?")
  button_ok=$(assuan_escape "Save")
  button_cancel=$(assuan_escape "Skip")

  {
    printf 'SETTITLE %s\n' "$title"
    printf 'SETDESC %s\n' "$description"
    printf 'SETOK %s\n' "$button_ok"
    printf 'SETCANCEL %s\n' "$button_cancel"
    printf 'CONFIRM\n'
  } | "$pinentry_program" >/dev/null 2>&1
}

if password=$(secret-tool lookup app udiskie id_uuid "$id_uuid" 2>/dev/null); then
  if [ -n "$password" ]; then
    printf '%s' "$password"
    exit 0
  fi
fi

password=$(pinentry_getpin) || exit 1

if [ -z "$password" ]; then
  exit 1
fi

if pinentry_confirm_save; then
  printf '%s' "$password" | secret-tool store \
    --label="udiskie LUKS $device_presentation" \
    app udiskie \
    id_uuid "$id_uuid" >/dev/null
fi

printf '%s' "$password"
