/*
 * get_pubkey_qrexec.c — connect to a running n_signer in another Qubes qube
 * via qrexec, using the high-level nostr_signer API from nostr_core_lib.
 *
 * This demonstrates the new nostr_core_lib client features:
 *   - nostr_signer_nsigner_qrexec() — qrexec transport
 *   - nostr_signer_nsigner_set_nostr_index() — index-based key selection
 *
 * Usage:
 *   ./get_pubkey_qrexec <target_qube> [nostr_index]
 *   ./get_pubkey_qrexec nostr_signer 0
 *   ./get_pubkey_qrexec nostr_signer 1
 *
 * No auth envelope needed — qrexec identity comes from QREXEC_REMOTE_DOMAIN
 * on the server side.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "nostr_common.h"
#include "nostr_signer.h"
#include "nip019.h"

int main(int argc, char **argv) {
    const char *target_qube;
    const char *service_name = "qubes.NsignerRpc";
    int nostr_index = 0;
    nostr_signer_t *signer = NULL;
    char pubkey_hex[65];
    unsigned char pubkey_bytes[32];
    char npub[128];
    int rc;

    if (argc < 2) {
        fprintf(stderr, "Usage: %s <target_qube> [nostr_index]\n", argv[0]);
        return 1;
    }
    target_qube = argv[1];
    if (argc > 2) {
        nostr_index = atoi(argv[2]);
    }

    if (nostr_init() != NOSTR_SUCCESS) {
        fprintf(stderr, "failed to initialize crypto subsystem\n");
        return 1;
    }

    printf("Connecting to n_signer in qube \"%s\" via qrexec (index %d)...\n",
           target_qube, nostr_index);

    /* Create a high-level signer backed by qrexec transport */
    signer = nostr_signer_nsigner_qrexec(target_qube, service_name, NULL, 30000);
    if (signer == NULL) {
        fprintf(stderr, "failed to create qrexec signer (is qrexec-client-vm available?)\n");
        nostr_cleanup();
        return 1;
    }

    /* Select key by nostr_index (NIP-06 m/44'/1237'/N'/0/0) */
    if (nostr_signer_nsigner_set_nostr_index(signer, nostr_index) != NOSTR_SUCCESS) {
        fprintf(stderr, "failed to set nostr_index\n");
        nostr_signer_free(signer);
        nostr_cleanup();
        return 1;
    }

    /* Request the public key */
    rc = nostr_signer_get_public_key(signer, pubkey_hex);
    if (rc != NOSTR_SUCCESS) {
        if (rc == NOSTR_ERROR_NSIGNER_INDEX_NOT_ALLOWED) {
            fprintf(stderr, "DENIED: index %d is not in the signer's whitelist\n", nostr_index);
        } else if (rc == NOSTR_ERROR_NSIGNER_POLICY_DENIED) {
            fprintf(stderr, "DENIED: policy denied (caller not approved at signer terminal)\n");
        } else {
            fprintf(stderr, "get_public_key failed: error code %d\n", rc);
        }
        nostr_signer_free(signer);
        nostr_cleanup();
        return 1;
    }

    /* Convert hex pubkey to npub (bech32) */
    {
        int i;
        for (i = 0; i < 32; i++) {
            unsigned int byte;
            if (sscanf(pubkey_hex + 2 * i, "%2x", &byte) != 1) {
                fprintf(stderr, "failed to parse hex pubkey\n");
                nostr_signer_free(signer);
                nostr_cleanup();
                return 1;
            }
            pubkey_bytes[i] = (unsigned char)byte;
        }
    }
    if (nostr_key_to_bech32(pubkey_bytes, "npub", npub) != NOSTR_SUCCESS) {
        fprintf(stderr, "failed to convert to npub\n");
        nostr_signer_free(signer);
        nostr_cleanup();
        return 1;
    }

    printf("index %d: hex=%s  npub=%s\n", nostr_index, pubkey_hex, npub);

    nostr_signer_free(signer);
    nostr_cleanup();
    return 0;
}
