#!/bin/sh

# pinentry-wrapper v0.1
# Customize pinentry prompts using environment variables
# Copyright (c) 2026 Raphaël Halimi <raphael.halimi@gmail.com>


#
# Variables
#

SCRIPT_NAME="${0##*/}"
SUPPORTED="TITLE PROMPT DESC ERROR OK CANCEL NOTOK"


#
# Functions
#

# Debug
print_debug () { [ "$DEBUG" ] && printf "%s\n" "$@" >&2 ; }

# Die
die () { printf "ERROR: %s, aborting.\n" "${1:-Fatal error}" >&2 ; exit 1 ; }

# Set options from the supported list
set_options () {
  for ITEM in $SUPPORTED ; do
    eval VAL="\"\$SET$ITEM\""
    if [ "$VAL" ] ; then
      SEND="SET$ITEM $VAL"
      print_debug "PRE: $SEND"
      printf "%s\n" "$SEND"
    fi
  done
}

# Loop for pinentry STDIN
pinentry_in () {
  local IN
  set_options
  if [ "$SETONLY" ] ; then
    while read IN ; do
      print_debug "IN: $IN"
      printf "%s\n" "$IN"
      case "$IN" in
        bye|BYE) break ;;
      esac
    done
  else
    printf "GETPIN\n"
  fi
}

# Loop for pinentry STDOUT
pinentry_out () {
  local OUT COUNTER
  COUNTER=0
  while read OUT ; do
    print_debug "OUT: $OUT"
    if [ $COUNTER -lt $SKIP ] ; then
      print_debug "skipping '$OUT'"
      COUNTER=$((COUNTER+1))
      continue
    fi
    if [ "$SETONLY" ] ; then
      printf "%s\n" "$OUT"
    else
      case "$OUT" in
        'D '*) printf "%s" "${OUT#D }" ; break ;;
        ERR*) printf "%s\n" "$OUT" >&2 ; return 1 ;
      esac
    fi
  done
}


#
# Checks
#

# Dependencies
for COMMAND in pinentry ; do
  command -v "$COMMAND" >/dev/null || die "Command '$COMMAND' not found"
done

# Options
for OPT ; do
  case "$OPT" in
    -h|--help|--version) pinentry "$@" ; exit $? ;;
  esac
done

# Debug
[ "$DEBUG" ] && set -- "$@" --debug


#
# Main
#

# Set the number of "OK" answers to skip
SKIP=0
for ITEM in $SUPPORTED ; do
  eval VAL="\"\$SET$ITEM\""
  [ "$VAL" ] && SKIP=$((SKIP+1))
done
print_debug "SKIP=$SKIP"

# Run pinentry
pinentry_in | pinentry "$@" | pinentry_out
