#!/bin/bash

passstore_Verzeichnis=$(
  readlink -f ~/.password-store
)

Verwendung() {
  >&2 echo 'Neues Passwort erzeugen.'
  >&2 echo ''
  >&2 printf 'Verwendung: %s [OPTIONS]\n' "$(basename "$0")"
  >&2 echo ''
  >&2 echo '  -p,--Pfad=Pfad/zum/Passwort'
  >&2 echo '  -x,--Extras'
  >&2 echo '  -z,--zufaellig[=Laenge]'
  >&2 echo \
'  --help                  display this help and exit
  --version               display version and exit'
  exit $1
}

eval set -- "$(
  getopt -o p:xz:: \
    --long Extras \
    --long help \
    --long Pfad: \
    --long version \
    --long zufaellig:: \
    -n "$(basename "$0")" \
    -- "$@" \
    || echo "Verwendung"
)"

Extras=false
Laenge=-1
Pfad=''
zufaellig=false

while true; do
  case "$1" in
    '--help')
      Verwendung 0
    ;;
    '-p'|'--Pfad')
      shift
      [ -z "${Pfad}" ] || Verwendung 1
      Pfad="$1"
    ;;
    '-x'|'--Extras')
      Extras=true
    ;;
    '--version')
      >&2 echo '0.8.1'
      exit 0
    ;;
    '-z'|'--zufaellig')
      shift
      [ ${Laenge} -eq -1 ] || Verwendung 1
      zufaellig=true
      [ -z "$1" ] && Laenge=16 || Laenge="$1"
      [ ${Laenge} -ge 0 ] || Verwendung 1
    ;;
    '--')
      shift
      break
    ;;
    *)
      >&2 printf 'FEHLER: Verstehe Option "%s" doch nicht!\n' "$1"
      exit 1
  esac
  shift
done

if [ ! -d "${passstore_Verzeichnis}" ]; then
  >&2 printf 'Verzeichnis "%s" existiert nicht - ist pass initialisiert?\n' "${passstore_Verzeichnis}"
  exit 1
fi

if [ $# -ne 0 ]; then
  >&2 printf 'FEHLER: Zu viele (%s) Argumente:\n' "$#"
  >&2 printf '"%s"\n' "$@"
  Verwendung 1
fi

if ! git -C "${passstore_Verzeichnis}" pull --rebase; then
  >&2 echo 'Kann passstore nicht rebasen.'
  exit 1
fi

if [ -z "${Pfad}" ]; then
  tree -d "${passstore_Verzeichnis}"
  read -r -p 'Pfad zum Passwort (Wildcards erlaubt): ' Pfad
  if [ -z "${Pfad}" ]; then
    >&2 echo 'Kein Pfad angegeben.'
    exit 1
  fi
fi

if [ -z "${Pfad%%*\**}" ]; then
  Pfad=$(
    printf '%s\n' "${Pfad}" \
    | tr '/' '\n' \
    | {
      p="${passstore_Verzeichnis}"
      while read -r dir; do
        if [ -n "${dir%%*\**}" ]; then
          p="${p}/${dir}"
        else
          p=$(
            printf '%s\n' "${p}/"${dir} \
            | head -n1
          )
        fi
      done
      echo "${p#${passstore_Verzeichnis}/}"
    }
  )
fi

if [ -d "${Pfad}" ]; then
  Pfad=$(readlink -e "${Pfad}")
  Pfad="${Pfad#${passstore_Verzeichnis}/}"
fi

if [ -z "${Pfad%%*/*}" ] && [ ! -d "${passstore_Verzeichnis}/${Pfad%/*}" ]; then
  printf 'Pfad "%s" existiert noch nicht - erstellen? (leer="ja")' "${Pfad%/*}"
  read -r Antwort
  if [ -n "${Antwort}" ]; then
    echo 'ok, dann nicht.'
    exit 1
  fi
fi

read -p 'URL:      ' URL
read -p 'Username: ' Benutzer
if [ ${Laenge} -lt 0 ]; then
  read -sp 'Passwort: ' pw1
  echo ''
  read -sp 'noch Mal: ' pw2
  echo ''
  if [ ! "${pw1}" == "${pw2}" ]; then
    >&2 echo 'Die Passwörter unterscheiden sich!'
    exit 1
  fi
else
  pw1=$(
    printf '%s\n' {0..1}{0..7}{0..7} \
    | sed '
      1,33d
      $d
    ' \
    | while read -r s; do
      printf '\'"$s"'\n'
    done \
    | shuf -n ${Laenge} --random-source=/dev/urandom -r \
    | tr -d '\n'
  )
fi

if ${Extras}; then
  tmp_file=$(mktemp)
  trap 'rm -f "${tmp_file}"' EXIT
  ${EDITOR:-nano} "${tmp_file}"
  Extrainfos=$(cat "${tmp_file}")
  rm -f "${tmp_file}"
  trap - EXIT
fi

{
  printf '%s\n' "${pw1}"
  printf 'URL: %s\n' "${URL}"
  printf 'Username: %s\n' "${Benutzer}"
  if ${Extras}; then
    printf '%s\n' "${Extrainfos}"
  fi
} \
| pass insert "${Pfad}" --multiline

git -C "${passstore_Verzeichnis}" push
