/*
 * NOSTR Core Library - Request Validator
 * 
 * Unified authentication and authorization system for NOSTR applications.
 * Provides rule-based validation for requests with pluggable database backends.
 * 
 * This module combines basic NOSTR event validation with sophisticated 
 * authentication rules to provide a single entry point for request validation
 * across different NOSTR applications (ginxsom, c-relay, etc.).
 */

#ifndef NOSTR_REQUEST_VALIDATOR_H
#define NOSTR_REQUEST_VALIDATOR_H

#include "nostr_common.h"
#include <time.h>
#include <sqlite3.h>

#ifdef __cplusplus
extern "C" {
#endif

// Forward declaration for cJSON
struct cJSON;

// Authentication rule types
typedef enum {
    NOSTR_AUTH_RULE_PUBKEY_WHITELIST,
    NOSTR_AUTH_RULE_PUBKEY_BLACKLIST,
    NOSTR_AUTH_RULE_HASH_BLACKLIST,
    NOSTR_AUTH_RULE_MIME_WHITELIST,
    NOSTR_AUTH_RULE_MIME_BLACKLIST,
    NOSTR_AUTH_RULE_SIZE_LIMIT,
    NOSTR_AUTH_RULE_RATE_LIMIT,
    NOSTR_AUTH_RULE_CUSTOM
} nostr_auth_rule_type_t;

// Authentication request context
typedef struct {
    const char* operation;        // Operation type ("upload", "delete", "list", "publish")
    const char* auth_header;      // Raw authorization header (optional)
    struct cJSON* event;          // NOSTR event for validation (optional)
    
    // Resource context (for file/blob operations)
    const char* resource_hash;    // Resource hash (SHA-256, optional)
    const char* mime_type;        // MIME type (optional)
    long file_size;               // File size (optional)
    
    // Client context
    const char* client_ip;        // Client IP for rate limiting (optional)
    void* app_context;            // Application-specific context (optional)
} nostr_request_t;

// Authentication result
typedef struct {
    int valid;                    // 0 = invalid/denied, 1 = valid/allowed
    int error_code;               // NOSTR_SUCCESS or specific error code
    char reason[256];             // Human-readable reason for denial
    char pubkey[65];              // Extracted pubkey from validated event (if available)
    int rule_id;                  // Rule ID that made the decision (0 if no rule)
    int priority;                 // Priority of the rule that matched
    time_t cached_until;          // Cache expiration time
} nostr_request_result_t;

// Authentication rule definition
typedef struct {
    int rule_id;                  // Unique rule identifier
    nostr_auth_rule_type_t type;  // Rule type
    char operation[32];           // Target operation ("*", "upload", "delete", "publish", etc.)
    char target[256];             // Rule target (pubkey, hash, mime pattern, etc.)
    char value[256];              // Rule value (size limit, rate limit, custom data)
    int priority;                 // Rule priority (lower number = higher priority)
    int enabled;                  // 1 = enabled, 0 = disabled
    time_t expires_at;            // Expiration timestamp (0 = never expires)
    char description[512];        // Human-readable description
    time_t created_at;            // Creation timestamp
} nostr_auth_rule_t;

// Database backend interface (pluggable)
typedef struct nostr_auth_db_interface {
    const char* name;             // Backend name ("sqlite", "redis", etc.)
    
    // Database lifecycle
    int (*init)(const char* db_path, const char* app_name);
    void (*cleanup)(void);
    
    // Configuration management
    int (*get_config)(const char* key, char* value, size_t value_size);
    int (*set_config)(const char* key, const char* value);
    
    // Rule querying and management
    int (*query_rules)(const nostr_request_t* request, nostr_auth_rule_t** rules, int* count);
    int (*rule_add)(const nostr_auth_rule_t* rule);
    int (*rule_remove)(int rule_id);
    int (*rule_update)(const nostr_auth_rule_t* rule);
    int (*rule_list)(const char* operation, nostr_auth_rule_t** rules, int* count);
    
    // Caching operations
    int (*cache_get)(const char* cache_key, nostr_request_result_t* result);
    int (*cache_set)(const char* cache_key, const nostr_request_result_t* result, int ttl);
    int (*cache_clear)(void);
} nostr_auth_db_interface_t;

//=============================================================================
// CORE API FUNCTIONS
//=============================================================================

/**
 * Initialize the request validator system with application database
 * 
 * @param app_db_path Path to application's SQLite database
 * @param app_name Application name for logging/identification
 * @return NOSTR_SUCCESS on success, error code on failure
 */
int nostr_request_validator_init(const char* app_db_path, const char* app_name);

/**
 * Initialize with shared database (future use)
 * 
 * @param shared_db_path Path to shared authentication database
 * @param app_name Application name for logging/identification
 * @return NOSTR_SUCCESS on success, error code on failure
 */
int nostr_request_validator_init_shared(const char* shared_db_path, const char* app_name);

/**
 * Main request validation function - validates both NOSTR events and authentication rules
 * 
 * @param request Request context with operation, auth header, and resource details
 * @param result Result structure with validation outcome and details
 * @return NOSTR_SUCCESS on successful validation processing, error code on system failure
 */
int nostr_validate_request(const nostr_request_t* request, nostr_request_result_t* result);

/**
 * Check if authentication rules system is enabled
 * 
 * @return 1 if enabled, 0 if disabled
 */
int nostr_auth_rules_enabled(void);

/**
 * Cleanup request validator resources
 */
void nostr_request_validator_cleanup(void);

//=============================================================================
// CONVENIENCE FUNCTIONS
//=============================================================================

/**
 * Convenience function for upload validation (ginxsom integration)
 * 
 * @param pubkey Uploader public key (optional, extracted from auth if NULL)
 * @param auth_header Authorization header with NOSTR event
 * @param hash File hash (SHA-256)
 * @param mime_type File MIME type
 * @param file_size File size in bytes
 * @return NOSTR_SUCCESS if allowed, error code if denied
 */
int nostr_auth_check_upload(const char* pubkey, const char* auth_header, 
                           const char* hash, const char* mime_type, long file_size);

/**
 * Convenience function for delete validation (ginxsom integration)
 * 
 * @param pubkey Requester public key
 * @param auth_header Authorization header with NOSTR event
 * @param hash File hash to delete
 * @return NOSTR_SUCCESS if allowed, error code if denied
 */
int nostr_auth_check_delete(const char* pubkey, const char* auth_header, const char* hash);

/**
 * Convenience function for publish validation (c-relay integration)
 * 
 * @param pubkey Publisher public key
 * @param event NOSTR event to publish
 * @return NOSTR_SUCCESS if allowed, error code if denied
 */
int nostr_auth_check_publish(const char* pubkey, struct cJSON* event);

//=============================================================================
// RULE MANAGEMENT FUNCTIONS
//=============================================================================

/**
 * Add a new authentication rule
 * 
 * @param rule Rule definition to add
 * @return NOSTR_SUCCESS on success, error code on failure
 */
int nostr_auth_rule_add(const nostr_auth_rule_t* rule);

/**
 * Remove an authentication rule by ID
 * 
 * @param rule_id Rule ID to remove
 * @return NOSTR_SUCCESS on success, error code on failure
 */
int nostr_auth_rule_remove(int rule_id);

/**
 * Update an existing authentication rule
 * 
 * @param rule Updated rule definition
 * @return NOSTR_SUCCESS on success, error code on failure
 */
int nostr_auth_rule_update(const nostr_auth_rule_t* rule);

/**
 * List authentication rules for a specific operation
 * 
 * @param operation Target operation ("*" for all operations)
 * @param rules Pointer to receive allocated array of rules
 * @param count Pointer to receive number of rules returned
 * @return NOSTR_SUCCESS on success, error code on failure
 */
int nostr_auth_rule_list(const char* operation, nostr_auth_rule_t** rules, int* count);

/**
 * Free rule array allocated by nostr_auth_rule_list
 * 
 * @param rules Rule array to free
 * @param count Number of rules in array
 */
void nostr_auth_rules_free(nostr_auth_rule_t* rules, int count);

//=============================================================================
// DATABASE BACKEND MANAGEMENT
//=============================================================================

/**
 * Register a database backend implementation
 * 
 * @param backend Backend interface implementation
 * @return NOSTR_SUCCESS on success, error code on failure
 */
int nostr_auth_register_db_backend(const nostr_auth_db_interface_t* backend);

/**
 * Set active database backend by name
 * 
 * @param backend_name Name of backend to activate
 * @return NOSTR_SUCCESS on success, error code on failure
 */
int nostr_auth_set_db_backend(const char* backend_name);

//=============================================================================
// CACHE MANAGEMENT
//=============================================================================

/**
 * Clear authentication decision cache
 * 
 * @return NOSTR_SUCCESS on success, error code on failure
 */
int nostr_auth_cache_clear(void);

/**
 * Get cache statistics
 * 
 * @param hit_count Pointer to receive cache hit count
 * @param miss_count Pointer to receive cache miss count
 * @param entries Pointer to receive current number of cache entries
 * @return NOSTR_SUCCESS on success, error code on failure
 */
int nostr_auth_cache_stats(int* hit_count, int* miss_count, int* entries);

#ifdef __cplusplus
}
#endif

#endif /* NOSTR_REQUEST_VALIDATOR_H */