// WebSocket protocol structures and constants for C-Relay
// This header defines structures shared between main.c and websockets.c

#ifndef WEBSOCKETS_H
#define WEBSOCKETS_H

#include <pthread.h>
#include <libwebsockets.h>
#include <time.h>
#include "../nostr_core_lib/cjson/cJSON.h"
#include "config.h"  // For CLIENT_IP_MAX_LENGTH and MAX_SUBSCRIPTIONS_PER_CLIENT

// Constants
#define CHALLENGE_MAX_LENGTH 128
#define AUTHENTICATED_PUBKEY_MAX_LENGTH 65  // 64 hex + null

// Rate limiting constants for malformed requests
#define MAX_MALFORMED_REQUESTS_PER_HOUR 10
#define MALFORMED_REQUEST_BLOCK_DURATION 3600  // 1 hour in seconds
#define RATE_LIMIT_CLEANUP_INTERVAL 300        // 5 minutes

// Filter validation constants
#define MAX_FILTERS_PER_REQUEST 10
#define MAX_AUTHORS_PER_FILTER 100
#define MAX_IDS_PER_FILTER 100
#define MAX_KINDS_PER_FILTER 50
#define MAX_TAG_VALUES_PER_FILTER 100
#define MAX_KIND_VALUE 65535
#define MAX_TIMESTAMP_VALUE 2147483647  // Max 32-bit signed int
#define MAX_LIMIT_VALUE 5000
#define MAX_SEARCH_LENGTH 256
#define MAX_TAG_VALUE_LENGTH 1024

// Message queue node for proper libwebsockets pattern
struct message_queue_node {
    unsigned char* data;                    // Message data (with LWS_PRE space)
    size_t length;                         // Message length (without LWS_PRE)
    enum lws_write_protocol type;           // LWS_WRITE_TEXT, etc.
    struct message_queue_node* next;        // Next node in queue
};

// Enhanced per-session data with subscription management, NIP-42 authentication, and rate limiting
struct per_session_data {
    int authenticated;
    struct subscription* subscriptions;      // Head of this session's subscription list
    pthread_mutex_t session_lock;           // Per-session thread safety
    char client_ip[CLIENT_IP_MAX_LENGTH];   // Client IP for logging
    int subscription_count;                  // Number of subscriptions for this session
    time_t connection_established;           // When WebSocket connection was established

    // NIP-42 Authentication State
    char authenticated_pubkey[65];           // Authenticated public key (64 hex + null)
    char active_challenge[65];               // Current challenge for this session (64 hex + null)
    time_t challenge_created;                // When challenge was created
    time_t challenge_expires;                // Challenge expiration time
    int nip42_auth_required_events;          // Whether NIP-42 auth is required for EVENT submission
    int nip42_auth_required_subscriptions;   // Whether NIP-42 auth is required for REQ operations
    int auth_challenge_sent;                 // Whether challenge has been sent (0/1)

    // Rate limiting for subscription attempts
    int failed_subscription_attempts;        // Count of failed subscription attempts
    time_t last_failed_attempt;              // Timestamp of last failed attempt
    time_t rate_limit_until;                 // Time until rate limiting expires
    int consecutive_failures;                // Consecutive failed attempts for backoff

    // Rate limiting for malformed requests
    int malformed_request_count;             // Count of malformed requests in current hour
    time_t malformed_request_window_start;   // Start of current hour window
    time_t malformed_request_blocked_until;  // Time until blocked for malformed requests

    // Message queue for proper libwebsockets pattern (replaces single buffer)
    struct message_queue_node* message_queue_head;  // Head of message queue
    struct message_queue_node* message_queue_tail;  // Tail of message queue
    int message_queue_count;                  // Number of messages in queue
    int writeable_requested;                  // Flag: 1 if writeable callback requested
};

// NIP-11 HTTP session data structure for managing buffer lifetime
struct nip11_session_data {
    int type; // 0 for NIP-11
    char* json_buffer;
    size_t json_length;
    int headers_sent;
    int body_sent;
};

// Function declarations
int start_websocket_relay(int port_override, int strict_port);

// Message queue functions for proper libwebsockets pattern
int queue_message(struct lws* wsi, struct per_session_data* pss, const char* message, size_t length, enum lws_write_protocol type);
int process_message_queue(struct lws* wsi, struct per_session_data* pss);

// Auth rules checking function from request_validator.c
int check_database_auth_rules(const char *pubkey, const char *operation, const char *resource_hash);

#endif // WEBSOCKETS_H