#!/usr/bin/env bash

# Fingerprint state and the one privileged switch, for the Users page.
#
# Two independent facts make a working fingerprint login, and conflating them
# is how the feature usually confuses people: fprintd must hold at least one
# enrolled print (GNOME's Users panel owns that dialog, and Panama hands off
# to it), and PAM must be told to ask the reader at all, which on Fedora is
# authselect's `with-fingerprint` feature. This helper reports both and can
# flip the second.
#
# Usage:
#   panama-fingerprint status  -> {"reader":bool,"readerName":"","enrolled":[],"pamEnabled":bool,"error":""}
#   panama-fingerprint set-unlock on|off   (prompts through panama-sudo/polkit)
#
# authselect is baseline Fedora (it manages PAM for the whole install), and
# fprintd ships with Workstation; a machine with neither simply reports no
# reader, which hides the card.

set -uo pipefail

PANAMA_PATH="${PANAMA_PATH:-$HOME/.local/share/Panama}"

emit() {
    jq -cn \
        --argjson reader "$1" \
        --arg readerName "$2" \
        --argjson enrolled "$3" \
        --argjson pamEnabled "$4" \
        --arg error "$5" \
        '{reader: $reader, readerName: $readerName, enrolled: $enrolled,
          pamEnabled: $pamEnabled, error: $error}'
}

cmd_status() {
    command -v fprintd-list >/dev/null 2>&1 || { emit false "" '[]' false ""; return; }

    # fprintd-list both answers "is there a reader" (fprintd is bus-activated,
    # so this also copes with the daemon not running yet) and names the
    # enrolled fingers in one call.
    local listing
    # LC_ALL=C: the "no devices" match below reads fprintd's message, and a
    # translated daemon would turn every readerless non-English machine into
    # a permanent error card.
    if ! listing="$(LC_ALL=C timeout 10 fprintd-list "$USER" 2>&1)"; then
        # "No devices available" is the normal no-reader machine; anything
        # else is a real problem worth surfacing.
        if grep -qi 'no devices' <<<"$listing"; then
            emit false "" '[]' false ""
        else
            emit false "" '[]' false "fprintd did not answer: $(head -1 <<<"$listing")"
        fi
        return
    fi

    # "Fingerprints for user gib on FocalTech ... (press):" carries the reader
    # product name; " - #0: right-index-finger" lines carry the enrollment.
    local name enrolled pam
    name="$(sed -n 's/^Fingerprints for user [^ ]* on \(.*\) (\w*):$/\1/p' <<<"$listing" | head -1)"
    enrolled="$(sed -n 's/^ *- #[0-9]*: //p' <<<"$listing" | jq -Rn '[inputs]')"
    pam=false
    authselect current 2>/dev/null | grep -q 'with-fingerprint' && pam=true

    emit true "$name" "$enrolled" "$pam" ""
}

cmd_set_unlock() {
    local verb reason
    case "$1" in
        on)  verb=enable-feature
             reason="Turning on fingerprint login: telling PAM (via authselect) to ask the fingerprint reader when unlocking" ;;
        off) verb=disable-feature
             reason="Turning off fingerprint login: telling PAM (via authselect) to stop asking the fingerprint reader" ;;
        *)   echo 'panama-fingerprint set-unlock takes on|off' >&2; exit 1 ;;
    esac

    local sudo_cmd=(sudo)
    [[ -x "$PANAMA_PATH/bin/panama-sudo" ]] && sudo_cmd=(
        "$PANAMA_PATH/bin/panama-sudo" --reason "$reason" --
    )
    "${sudo_cmd[@]}" authselect "$verb" with-fingerprint
}

case "${1:-}" in
    status)     cmd_status ;;
    set-unlock) [[ -n "${2:-}" ]] || { echo 'panama-fingerprint set-unlock takes on|off' >&2; exit 1; }
                cmd_set_unlock "$2" ;;
    *)          echo 'usage: panama-fingerprint status | set-unlock on|off' >&2; exit 1 ;;
esac
