#! /bin/bash

set -e
set -o pipefail

shamir_secret_sharing=false

share_threshold=3

positional=()
while [ $# -gt 0 ]; do
  argument="$1"
  case $argument in
    -h|--help)
    printf "%s\n" \
    "Usage: qr-restore.sh [options]" \
    "" \
    "Options:" \
    "  --shamir-secret-sharing    combine secret using Shamir Secret Sharing" \
    "  --share-threshold          shares required to access secret (defaults to 3)" \
    "  --word-list                split secret into word list" \
    "  -h, --help                 display help for command"
    exit 0
    ;;
    --images)
    images=$2
    shift
    shift
    ;;
    --shamir-secret-sharing)
    shamir_secret_sharing=true
    shift
    ;;
    --share-threshold)
    share_threshold=$2
    shift
    shift
    ;;
    --word-list)
    word_list=true
    shift
    ;;
    *)
    positional+=("$1")
    shift
    ;;
  esac
done

set -- "${positional[@]}"

bold=$(tput bold)
red=$(tput setaf 1)
normal=$(tput sgr0)

dev="/dev/sda1"
tmp="/tmp/pi"
usb="/tmp/usb"

tput reset

if [ -n "$images" ]; then
  IFS=',' read -r -a images <<< "$images"

  sudo mkdir -p $usb

  if ! mount | grep $usb > /dev/null; then
    sudo mount $dev $usb --options uid=pi,gid=pi
  fi
fi

scan_qr_code () {
  local -n data=$1

  printf "%s\n" "Scanning QR code…"
  
  data=$(zbarcam --nodisplay --oneshot --quiet --set disable --set qrcode.enable | sed 's/QR-Code://')

  data_hash=$(echo -n "$data" | openssl dgst -sha512 | sed 's/^.* //')
  data_short_hash=$(echo -n "$data_hash" | head -c 8)

  printf "%s\n" "$data"
  printf "%s: $bold%s$normal\n" "SHA512 hash" "$data_hash"
  printf "%s: $bold%s$normal\n" "SHA512 short hash" "$data_short_hash"
}

read_passphrase () {
  local -n data=$1

  printf "$bold%s$normal\n" "Please type passphrase and press enter"
  read -rs data
}

if [ -z "$duplicate" ] && [ "$shamir_secret_sharing" = true ]; then
  read_passphrase passphrase

  if [ -n "$images" ]; then
    for image in ${images[@]}; do
      printf "%s\n" "Processing $image…"

      encrypted_share=$(zbarimg --quiet $usb/$image | sed 's/QR-Code://')

      share=$(echo -e "$encrypted_share" | gpg --batch --passphrase-fd 3 --decrypt 3<<<"$passphrase")

      shares="$share\n$shares"
    done
  else
    for share_number in $(seq 1 $share_threshold); do
      printf "$bold%s$normal" "Prepare secret share $share_number of $share_threshold and press enter"
      read -r confirmation

      scan_qr_code encrypted_share

      share=$(echo -e "$encrypted_share" | gpg --batch --passphrase-fd 3 --decrypt 3<<<"$passphrase")

      shares="$share\n$shares"
    done
  fi

  secret="$(echo -e "$shares" | secret-share-combine)"
else
  if [ -n "$images" ]; then
    printf "%s\n" "Processing ${images[0]}…"

    encrypted_secret=$(zbarimg --quiet $usb/${images[0]} | sed 's/QR-Code://')
  else
    scan_qr_code encrypted_secret
  fi
  if [ -z "$duplicate" ]; then
    read_passphrase passphrase
    
    secret=$(echo -e "$encrypted_secret" | gpg --batch --passphrase-fd 3 --decrypt 3<<<"$passphrase")
  fi
fi

if [ -z "$duplicate" ]; then
  printf "$bold$red%s$normal\n" "Show secret (y or n)?"
  read -r answer
  if [ "$answer" = "y" ]; then
    if [ "$word_list" = true ]; then
      printf "%s\n" "Secret:"
      array=($secret)
      last_index=$(echo "${#array[@]} - 1" | bc)
      for index in ${!array[@]}; do
        position=$(($index + 1))
        printf "%d. $bold%s$normal" "$position" "${array[$index]}"
        if [ $index -lt $last_index ]; then
          printf " "
        fi
      done
      printf "\n"
    else
      printf "%s\n" "Secret:"
      echo "$bold$secret$normal"
    fi
  fi
fi

if mount | grep $dev > /dev/null; then
  sudo umount $dev
fi

printf "%s\n" "Done"