#ifndef NOSTR_CORE_H
#define NOSTR_CORE_H

// Version information (auto-updated by increment_and_push.sh)
#define VERSION "v0.4.8"
#define VERSION_MAJOR 0
#define VERSION_MINOR 4
#define VERSION_PATCH 8

/*
 * NOSTR Core Library - Complete API Reference
 * 
 * This header includes ALL library functionality. For modular includes,
 * use individual headers instead.
 * 
 * ============================================================================
 * QUICK FUNCTION REFERENCE - Find what you need fast!
 * ============================================================================
 * 
 * EVENT OPERATIONS (NIP-01):
 *   - nostr_create_and_sign_event()     -> Create and sign new Nostr events
 *   - nostr_validate_event()            -> Validate complete Nostr event 
 *   - nostr_validate_event_structure()  -> Check event structure only
 *   - nostr_verify_event_signature()    -> Verify cryptographic signature
 * 
 * CRYPTOGRAPHIC HASHING:
 *   - nostr_sha256()                    -> Single-call SHA-256 hash
 *   - nostr_sha256_init()               -> Initialize streaming SHA-256 context
 *   - nostr_sha256_update()             -> Process data chunks incrementally
 *   - nostr_sha256_final()              -> Finalize hash and clear context
 *   - nostr_sha256_file_stream()        -> Hash large files efficiently (NEW!)
 *   - nostr_sha512()                    -> SHA-512 hash function
 *   - nostr_hmac_sha256()               -> HMAC with SHA-256
 *   - nostr_hmac_sha512()               -> HMAC with SHA-512
 * 
 * DIGITAL SIGNATURES & KEYS:
 *   - nostr_schnorr_sign()              -> Create Schnorr signatures
 *   - nostr_ec_public_key_from_private_key() -> Generate public keys
 *   - nostr_ec_private_key_verify()     -> Validate private key format
 *   - nostr_ec_sign()                   -> ECDSA signature creation
 *   - nostr_rfc6979_generate_k()        -> Deterministic nonce generation
 * 
 * NIP-04 ENCRYPTION (Legacy):
 *   - nostr_nip04_encrypt()             -> Encrypt messages (AES-256-CBC)
 *   - nostr_nip04_decrypt()             -> Decrypt messages (AES-256-CBC)
 * 
 * NIP-44 ENCRYPTION (Modern - Recommended):
 *   - nostr_nip44_encrypt()             -> Encrypt with ChaCha20 + HMAC
 *   - nostr_nip44_encrypt_with_nonce()  -> Encrypt with specific nonce (testing)
 *   - nostr_nip44_decrypt()             -> Decrypt ChaCha20 + HMAC messages
 *
 * NIP-59 GIFT WRAP:
 *   - nostr_nip59_create_rumor()        -> Create unsigned event (rumor)
 *   - nostr_nip59_create_seal()         -> Seal rumor with sender's key (kind 13)
 *   - nostr_nip59_create_gift_wrap()    -> Wrap seal with random key (kind 1059)
 *   - nostr_nip59_unwrap_gift()         -> Unwrap gift wrap to get seal
 *   - nostr_nip59_unseal_rumor()        -> Unseal to get original rumor
 *
 * NIP-17 PRIVATE DIRECT MESSAGES:
 *   - nostr_nip17_create_chat_event()   -> Create chat message (kind 14)
 *   - nostr_nip17_create_file_event()   -> Create file message (kind 15)
 *   - nostr_nip17_create_relay_list_event() -> Create DM relay list (kind 10050)
 *   - nostr_nip17_send_dm()             -> Send DM to multiple recipients
 *   - nostr_nip17_receive_dm()          -> Receive and decrypt DM
 *   - nostr_nip17_extract_dm_relays()   -> Extract relay URLs from kind 10050
 *
 * NIP-42 AUTHENTICATION:
 *   - nostr_nip42_create_auth_event()   -> Create authentication event (kind 22242)
 *   - nostr_nip42_verify_auth_event()   -> Verify authentication event (relay-side)
 *   - nostr_nip42_generate_challenge()  -> Generate challenge string (relay-side)
 *   - nostr_ws_authenticate()           -> Authenticate WebSocket client
 *   - nostr_ws_get_auth_state()         -> Get client authentication state
 *
 * BIP39 MNEMONICS:
 *   - nostr_bip39_mnemonic_from_bytes() -> Generate mnemonic from entropy
 *   - nostr_bip39_mnemonic_validate()   -> Validate mnemonic phrase
 *   - nostr_bip39_mnemonic_to_seed()    -> Convert mnemonic to seed
 * 
 * BIP32 HD WALLETS:
 *   - nostr_bip32_key_from_seed()       -> Create master key from seed
 *   - nostr_bip32_derive_child()        -> Derive child key from parent
 *   - nostr_bip32_derive_path()         -> Derive keys from derivation path
 * 
 * KEY DERIVATION:
 *   - nostr_hkdf()                      -> HKDF key derivation (full)
 *   - nostr_hkdf_extract()              -> HKDF extract step only
 *   - nostr_hkdf_expand()               -> HKDF expand step only
 *   - nostr_pbkdf2_hmac_sha512()        -> PBKDF2 with HMAC-SHA512
 *   - ecdh_shared_secret()              -> ECDH shared secret computation
 * 
 * UTILITIES & ENCODING:
 *   - nostr_bytes_to_hex()              -> Convert bytes to hex string
 *   - nostr_hex_to_bytes()              -> Convert hex string to bytes
 *   - base64_encode()                   -> Base64 encoding
 *   - base64_decode()                   -> Base64 decoding
 *
 * REQUEST VALIDATION & AUTHENTICATION:
 *   - nostr_validate_request()          -> Unified request validation (events + auth rules)
 *   - nostr_request_validator_init()    -> Initialize authentication system
 *   - nostr_auth_check_upload()         -> Validate file upload requests
 *   - nostr_auth_check_delete()         -> Validate file delete requests
 *   - nostr_auth_check_publish()        -> Validate event publish requests
 *   - nostr_auth_rule_add()             -> Add authentication rule
 *   - nostr_auth_rule_remove()          -> Remove authentication rule
 *
 * RELAY OPERATIONS:
 *   - synchronous_query_relays_with_progress() -> One-off query from multiple relays
 *   - synchronous_publish_event_with_progress() -> One-off publish to multiple relays
 * *
 * RELAY POOL OPERATIONS:
 *   - nostr_relay_pool_create()         -> Create relay pool for persistent connections
 *   - nostr_relay_pool_subscribe()      -> Subscribe to events with callbacks
 *   - nostr_relay_pool_run()            -> Run event loop for receiving events

 * SYSTEM FUNCTIONS:
 *   - nostr_crypto_init()               -> Initialize crypto subsystem
 *   - nostr_crypto_cleanup()            -> Cleanup crypto subsystem
 * 
 * ============================================================================
 * USAGE EXAMPLES:
 * ============================================================================
 * 
 * Basic Event Creation:
 *   cJSON* event = nostr_create_and_sign_event(1, "Hello Nostr!", NULL, private_key, time(NULL));
 *   if (nostr_validate_event(event) == NOSTR_SUCCESS) { ... }
 * 
 * Streaming SHA-256 (for large files):
 *   nostr_sha256_ctx_t ctx;
 *   nostr_sha256_init(&ctx);
 *   // Process data in chunks...
 *   nostr_sha256_update(&ctx, data, data_size);
 *   nostr_sha256_final(&ctx, hash_output);
 * 
 * File Hashing:
 *   unsigned char file_hash[32];
 *   nostr_sha256_file_stream("large_video.mp4", file_hash);
 * 
 * Modern Encryption (NIP-44):
 *   nostr_nip44_encrypt(sender_key, recipient_pubkey, "secret message", output, sizeof(output));
 * 
 * HD Wallet Derivation:
 *   nostr_bip32_key_from_seed(seed, 64, &master_key);
 *   uint32_t path[] = {44, 1237, 0, 0, 0}; // m/44'/1237'/0'/0/0
 *   nostr_bip32_derive_path(&master_key, path, 5, &derived_key);
 *
 * Client Authentication (NIP-42):
 *   cJSON* auth_event = nostr_nip42_create_auth_event(challenge, relay_url, private_key, 0);
 *   nostr_ws_authenticate(client, private_key, 600); // Auto-authenticate WebSocket
 *
 * Private Direct Messages (NIP-17):
 *   // Create and send a DM
 *   cJSON* dm_event = nostr_nip17_create_chat_event("Hello!", &recipient_pubkey, 1, NULL, NULL, NULL, sender_pubkey);
 *   cJSON* gift_wraps[10];
 *   int count = nostr_nip17_send_dm(dm_event, &recipient_pubkey, 1, sender_privkey, gift_wraps, 10);
 *   // Publish gift_wraps[0] to recipient's relays
 *
 *   // Receive a DM
 *   cJSON* decrypted_dm = nostr_nip17_receive_dm(received_gift_wrap, recipient_privkey);
 *
 * ============================================================================
 */

#ifdef __cplusplus
extern "C" {
#endif

// Core common definitions and utilities
#include "nostr_common.h"
#include "utils.h"

// NIP implementations
#include "nip001.h"  // Basic Protocol
#include "nip004.h"  // Encryption (legacy)
#include "nip005.h"  // DNS-based identifiers
#include "nip006.h"  // Key derivation from mnemonic
#include "nip011.h"  // Relay information document
#include "nip013.h"  // Proof of Work
#include "nip017.h"  // Private Direct Messages
#include "nip019.h"  // Bech32 encoding (nsec/npub)
#include "nip021.h"  // nostr: URI scheme
#include "nip042.h"  // Authentication of clients to relays
#include "nip044.h"  // Encryption (modern)
#include "nip059.h"  // Gift Wrap

// Authentication and request validation system
#include "request_validator.h"  // Request validation and authentication rules

// Relay pool types and functions
typedef enum {
    NOSTR_POOL_RELAY_DISCONNECTED = 0,
    NOSTR_POOL_RELAY_CONNECTING = 1,
    NOSTR_POOL_RELAY_CONNECTED = 2,
    NOSTR_POOL_RELAY_ERROR = -1
} nostr_pool_relay_status_t;

// EOSE result mode for subscriptions
typedef enum {
    NOSTR_POOL_EOSE_FULL_SET,      // Wait for all relays, return all events
    NOSTR_POOL_EOSE_MOST_RECENT,   // Wait for all relays, return most recent event
    NOSTR_POOL_EOSE_FIRST          // Return results on first EOSE (fastest response)
} nostr_pool_eose_result_mode_t;

typedef struct {
    int connection_attempts;
    int connection_failures;
    int events_received;
    int events_published;
    int events_published_ok;
    int events_published_failed;
    time_t last_event_time;
    time_t connection_uptime_start;
    double ping_latency_avg;
    double ping_latency_min;
    double ping_latency_max;
    double ping_latency_current;
    int ping_samples;
    double query_latency_avg;
    double query_latency_min;
    double query_latency_max;
    int query_samples;
    double publish_latency_avg;
    int publish_samples;
} nostr_relay_stats_t;

typedef struct nostr_relay_pool nostr_relay_pool_t;
typedef struct nostr_pool_subscription nostr_pool_subscription_t;

// Reconnection configuration
typedef struct {
    int enable_auto_reconnect;        // 1 = enable, 0 = disable
    int max_reconnect_attempts;       // Max attempts per relay
    int initial_reconnect_delay_ms;   // Initial delay between attempts
    int max_reconnect_delay_ms;       // Max delay (cap exponential backoff)
    int reconnect_backoff_multiplier; // Delay multiplier
    int ping_interval_seconds;        // How often to ping (0 = disable)
    int pong_timeout_seconds;         // How long to wait for pong before reconnecting
} nostr_pool_reconnect_config_t;

// Relay pool management functions
nostr_relay_pool_t* nostr_relay_pool_create(nostr_pool_reconnect_config_t* config);
nostr_pool_reconnect_config_t* nostr_pool_reconnect_config_default(void);
int nostr_relay_pool_add_relay(nostr_relay_pool_t* pool, const char* relay_url);
int nostr_relay_pool_remove_relay(nostr_relay_pool_t* pool, const char* relay_url);
void nostr_relay_pool_destroy(nostr_relay_pool_t* pool);

// Subscription management
nostr_pool_subscription_t* nostr_relay_pool_subscribe(
    nostr_relay_pool_t* pool,
    const char** relay_urls,
    int relay_count,
    cJSON* filter,
    void (*on_event)(cJSON* event, const char* relay_url, void* user_data),
    void (*on_eose)(cJSON** events, int event_count, void* user_data),
    void* user_data,
    int close_on_eose,
    int enable_deduplication,
    nostr_pool_eose_result_mode_t result_mode,
    int relay_timeout_seconds,
    int eose_timeout_seconds);
int nostr_pool_subscription_close(nostr_pool_subscription_t* subscription);

// Backward compatibility wrapper
nostr_pool_subscription_t* nostr_relay_pool_subscribe_compat(
    nostr_relay_pool_t* pool,
    const char** relay_urls,
    int relay_count,
    cJSON* filter,
    void (*on_event)(cJSON* event, const char* relay_url, void* user_data),
    void (*on_eose)(void* user_data),
    void* user_data,
    int close_on_eose);

// Event loop functions
int nostr_relay_pool_run(nostr_relay_pool_t* pool, int timeout_ms);
int nostr_relay_pool_poll(nostr_relay_pool_t* pool, int timeout_ms);

// Synchronous query/publish functions
cJSON** nostr_relay_pool_query_sync(
    nostr_relay_pool_t* pool,
    const char** relay_urls,
    int relay_count,
    cJSON* filter,
    int* event_count,
    int timeout_ms);
cJSON* nostr_relay_pool_get_event(
    nostr_relay_pool_t* pool,
    const char** relay_urls,
    int relay_count,
    cJSON* filter,
    int timeout_ms);
// Async publish callback typedef
typedef void (*publish_response_callback_t)(
    const char* relay_url,
    const char* event_id,
    int success,           // 1 for OK, 0 for rejection
    const char* message,   // Error message if rejected, NULL if success
    void* user_data
);

// Async publish function (only async version available)
int nostr_relay_pool_publish_async(
    nostr_relay_pool_t* pool,
    const char** relay_urls,
    int relay_count,
    cJSON* event,
    publish_response_callback_t callback,
    void* user_data);

// Status and statistics functions
nostr_pool_relay_status_t nostr_relay_pool_get_relay_status(
    nostr_relay_pool_t* pool,
    const char* relay_url);
int nostr_relay_pool_list_relays(
    nostr_relay_pool_t* pool,
    char*** relay_urls,
    nostr_pool_relay_status_t** statuses);
const nostr_relay_stats_t* nostr_relay_pool_get_relay_stats(
    nostr_relay_pool_t* pool,
    const char* relay_url);
int nostr_relay_pool_reset_relay_stats(
    nostr_relay_pool_t* pool,
    const char* relay_url);
double nostr_relay_pool_get_relay_query_latency(
    nostr_relay_pool_t* pool,
    const char* relay_url);
const char* nostr_relay_pool_get_relay_last_publish_error(
    nostr_relay_pool_t* pool,
    const char* relay_url);
const char* nostr_relay_pool_get_relay_last_connection_error(
    nostr_relay_pool_t* pool,
    const char* relay_url);
double nostr_relay_pool_get_relay_ping_latency(
    nostr_relay_pool_t* pool,
    const char* relay_url);

// Synchronous relay operations (one-off queries/publishes)
typedef enum {
    RELAY_QUERY_FIRST_RESULT,   // Return as soon as first event is received
    RELAY_QUERY_MOST_RECENT,    // Return the most recent event from all relays
    RELAY_QUERY_ALL_RESULTS     // Return all unique events from all relays
} relay_query_mode_t;

typedef enum {
    PUBLISH_SUCCESS,    // Event was accepted by relay
    PUBLISH_REJECTED,   // Event was rejected by relay
    PUBLISH_TIMEOUT,    // No response within timeout
    PUBLISH_ERROR       // Connection or other error
} publish_result_t;

typedef void (*relay_progress_callback_t)(
    const char* relay_url,
    const char* status,
    const char* event_id,
    int events_received,
    int total_relays,
    int completed_relays,
    void* user_data);

typedef void (*publish_progress_callback_t)(
    const char* relay_url,
    const char* status,
    const char* message,
    int success_count,
    int total_relays,
    int completed_relays,
    void* user_data);

// Synchronous relay query functions
struct cJSON** synchronous_query_relays_with_progress(
    const char** relay_urls,
    int relay_count,
    struct cJSON* filter,
    relay_query_mode_t mode,
    int* result_count,
    int relay_timeout_seconds,
    relay_progress_callback_t callback,
    void* user_data,
    int nip42_enabled,
    const unsigned char* private_key);

// Synchronous relay publish functions
publish_result_t* synchronous_publish_event_with_progress(
    const char** relay_urls,
    int relay_count,
    struct cJSON* event,
    int* success_count,
    int relay_timeout_seconds,
    publish_progress_callback_t callback,
    void* user_data,
    int nip42_enabled,
    const unsigned char* private_key);

// Relay communication functions are defined in nostr_common.h
// WebSocket functions are defined in nostr_common.h

#ifdef __cplusplus
}
#endif

#endif /* NOSTR_CORE_H */
