/*
 * Synchronous Relay Query Test Program
 * 
 * Tests the synchronous_query_relays_with_progress function
 * with all three query modes: FIRST_RESULT, MOST_RECENT, ALL_RESULTS
 * 
 * Usage: Uncomment only ONE test mode at the top of main()
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "../nostr_core/nostr_core.h"
#include "../cjson/cJSON.h"

// Helper function to get mode name for display
const char* get_mode_name(relay_query_mode_t mode) {
    switch (mode) {
        case RELAY_QUERY_FIRST_RESULT: return "FIRST_RESULT";
        case RELAY_QUERY_MOST_RECENT: return "MOST_RECENT";
        case RELAY_QUERY_ALL_RESULTS: return "ALL_RESULTS";
        default: return "UNKNOWN";
    }
}

// Progress callback to show raw relay activity
void progress_callback(const char* relay_url, const char* status, 
                      const char* event_id, int events_received, 
                      int total_relays, int completed_relays, void* user_data) {
    (void)user_data; // Unused parameter
    
    printf("[PROGRESS] ");
    if (relay_url) {
        printf("%s | %s", relay_url, status);
        if (event_id) {
            printf(" | Event: %.12s...", event_id);
        }
        printf(" | Events: %d | Relays: %d/%d\n", 
               events_received, completed_relays, total_relays);
    } else {
        printf("SUMMARY | %s | Events: %d | Relays: %d/%d\n",
               status, events_received, completed_relays, total_relays);
    }
    fflush(stdout);
}

int main() {
    // Initialize NOSTR library
    if (nostr_init() != NOSTR_SUCCESS) {
        fprintf(stderr, "Failed to initialize NOSTR library\n");
        return 1;
    }
    
    // ============================================================================
    // TEST SELECTION - Uncomment only ONE test at a time
    // ============================================================================
    
    // relay_query_mode_t test_mode = RELAY_QUERY_FIRST_RESULT;
    // relay_query_mode_t test_mode = RELAY_QUERY_MOST_RECENT;
    relay_query_mode_t test_mode = RELAY_QUERY_ALL_RESULTS;
    
    // ============================================================================
    // Hard-coded test configuration
    // ============================================================================
    
    const char* test_relays[] = {
        "ws://127.0.0.1:7777",
        "wss://relay.laantungir.net", 
        "wss://relay.corpum.com"
    };
    int relay_count = 3;
    
    // ============================================================================
    // FILTER CONFIGURATION - Edit this JSON string to change the query
    // ============================================================================
    
    const char* filter_json = 
        "{"
        "  \"kinds\": [1],"
        "  \"limit\": 1"
        "}";
    
    // Alternative filter examples (comment out the one above, uncomment one below):
    
    // Get kind 0 (profile) events:
    // const char* filter_json = "{\"kinds\": [0], \"limit\": 5}";
    
    // Get events from specific author (replace with real pubkey):
    // const char* filter_json = "{\"authors\": [\"e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411\"], \"kinds\": [1], \"limit\": 20}";
    
    // Get recent events with specific hashtag:
    // const char* filter_json = "{\"kinds\": [1], \"#t\": [\"nostr\"], \"limit\": 15}";
    
    // Get events since specific timestamp:
    // const char* filter_json = "{\"kinds\": [1], \"since\": 1706825234, \"limit\": 10}";
    
    // Parse the filter JSON string
    cJSON* filter = cJSON_Parse(filter_json);
    if (!filter) {
        fprintf(stderr, "ERROR: Failed to parse filter JSON:\n%s\n", filter_json);
        fprintf(stderr, "Check JSON syntax and try again.\n");
        nostr_cleanup();
        return 1;
    }
    
    // ============================================================================
    // Run the test
    // ============================================================================
    
    printf("=== SYNCHRONOUS RELAY QUERY TEST ===\n");
    printf("Mode: %s\n", get_mode_name(test_mode));
    printf("Querying %d relays with 5 second timeout...\n\n", relay_count);
    
    // Print relay list
    printf("Test relays:\n");
    for (int i = 0; i < relay_count; i++) {
        printf("  %d. %s\n", i + 1, test_relays[i]);
    }
    printf("\n");
    
    // Print filter
    char* filter_str = cJSON_Print(filter);
    printf("Filter: %s\n\n", filter_str);
    free(filter_str);
    
    int result_count = 0;
    time_t start_time = time(NULL);
    
    printf("Starting query...\n\n");
    
    cJSON** results = synchronous_query_relays_with_progress(
        test_relays, relay_count, filter, test_mode,
        &result_count, 5, progress_callback, NULL
    );
    
    time_t end_time = time(NULL);
    
    // ============================================================================
    // Print raw results
    // ============================================================================
    
    printf("\n=== RAW RESULTS ===\n");
    printf("Execution time: %ld seconds\n", end_time - start_time);
    printf("Events returned: %d\n\n", result_count);
    
    if (results && result_count > 0) {
        for (int i = 0; i < result_count; i++) {
            printf("--- EVENT %d ---\n", i + 1);
            char* json_str = cJSON_Print(results[i]);
            if (json_str) {
                printf("%s\n\n", json_str);
                free(json_str);
            } else {
                printf("ERROR: Failed to serialize event to JSON\n\n");
            }
        }
    } else {
        printf("No events returned.\n\n");
    }
    
    // ============================================================================
    // Cleanup
    // ============================================================================
    
    if (results) {
        for (int i = 0; i < result_count; i++) {
            if (results[i]) {
                cJSON_Delete(results[i]);
            }
        }
        free(results);
    }
    
    cJSON_Delete(filter);
    nostr_cleanup();
    
    printf("Test completed.\n");
    return 0;
}
