#!/usr/bin/env bash
# =============================================================================
# onx-gpg-key-list — List keys in a user's ~/.gnupg
#
# Input:  { "username": "onx_xxxx" }
# Output: { "username":"...", "count": N, "keys": [
#            {"fingerprint":"...", "key_id":"...", "uid":"...",
#             "key_size": 2048, "created_at":"YYYY-MM-DD",
#             "expires_at":"YYYY-MM-DD"|null, "has_private": true|false}
#          ]}
#
# Exit codes: 0=ok 1=invalid-input 2=preflight-fail
# Deployed to: /usr/local/onoxsoft/bin/onx-gpg-key-list
# =============================================================================

set -euo pipefail

SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
source "${SCRIPT_DIR}/_lib/common.sh"

require_cmd jq
require_cmd gpg

INPUT=$(cat)
onx_require_json "${INPUT}"

USERNAME=$(onx_json_get "${INPUT}" "username")
onx_validate_username "${USERNAME}"
id "${USERNAME}" &>/dev/null || onx_die 2 "Linux user does not exist: ${USERNAME}"

GNUPGHOME="/home/${USERNAME}/.gnupg"

if [[ ! -d "${GNUPGHOME}" ]]; then
    printf '{"username":"%s","count":0,"keys":[]}\n' "${USERNAME}"
    exit 0
fi

# Pull secret fingerprints first (so we can flag has_private)
SECRET_FPRS=$(su -s /bin/bash "${USERNAME}" -c \
    "gpg --homedir '${GNUPGHOME}' --list-secret-keys --with-colons --with-fingerprint 2>/dev/null" \
    | awk -F: '/^fpr/ {print $10}' | sort -u || true)

# Walk public list
KEYS_JSON='['
SEP=""
PUB_OUTPUT=$(su -s /bin/bash "${USERNAME}" -c \
    "gpg --homedir '${GNUPGHOME}' --list-keys --with-colons --with-fingerprint --with-fingerprint 2>/dev/null" \
    || echo "")

current_fpr=""; current_size=""; current_created=""; current_expires=""; current_uid=""

emit_key() {
    [[ -z "${current_fpr}" ]] && return
    local has_priv="false"
    if echo "${SECRET_FPRS}" | grep -qx "${current_fpr}"; then
        has_priv="true"
    fi
    local key_id="${current_fpr:24:16}"
    local exp_field
    if [[ -n "${current_expires}" && "${current_expires}" != "0" ]]; then
        exp_field=$(date -u -d "@${current_expires}" '+%Y-%m-%d' 2>/dev/null || echo "")
        exp_field="\"${exp_field}\""
    else
        exp_field="null"
    fi
    local cre_field
    if [[ -n "${current_created}" ]]; then
        cre_field=$(date -u -d "@${current_created}" '+%Y-%m-%d' 2>/dev/null || echo "")
        cre_field="\"${cre_field}\""
    else
        cre_field="null"
    fi
    local uid_json
    uid_json=$(printf '%s' "${current_uid}" | jq -Rs '.')
    KEYS_JSON+="${SEP}{\"fingerprint\":\"${current_fpr}\",\"key_id\":\"${key_id}\",\"uid\":${uid_json},\"key_size\":${current_size:-0},\"created_at\":${cre_field},\"expires_at\":${exp_field},\"has_private\":${has_priv}}"
    SEP=","
}

while IFS=: read -r kind validity length algo keyid created expires user usage owner uid_field rest; do
    case "${kind}" in
        pub)
            emit_key
            current_fpr=""; current_size="${length}"; current_created="${created}"; current_expires="${expires}"; current_uid=""
            ;;
        fpr)
            if [[ -z "${current_fpr}" ]]; then
                current_fpr="${user}"
            fi
            ;;
        uid)
            if [[ -z "${current_uid}" ]]; then
                current_uid="${user}"
            fi
            ;;
    esac
done <<< "${PUB_OUTPUT}"
emit_key

KEYS_JSON+="]"

COUNT=$(echo "${KEYS_JSON}" | jq 'length' 2>/dev/null || echo 0)
printf '{"username":"%s","count":%s,"keys":%s}\n' "${USERNAME}" "${COUNT}" "${KEYS_JSON}"
