#define _DEFAULT_SOURCE
#include "../nostr_core/nostr_core.h"
#include "../cjson/cJSON.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

// Test callback function
static int callback_count = 0;
static int success_count = 0;

void test_callback(const char* relay_url, const char* event_id, 
                   int success, const char* message, void* user_data) {
    callback_count++;
    if (success) {
        success_count++;
    }
    
    printf("📡 Callback %d: Relay %s, Event %s, Success: %s\n", 
           callback_count, relay_url, event_id, success ? "YES" : "NO");
    if (message) {
        printf("   Message: %s\n", message);
    }
    
    // Mark test as complete when we get the expected number of callbacks
    int* expected_callbacks = (int*)user_data;
    if (callback_count >= *expected_callbacks) {
        printf("✅ All callbacks received!\n");
    }
}

int main() {
    printf("🧪 Testing Async Publish Functionality\n");
    printf("=====================================\n");
    
    // Create pool
    nostr_relay_pool_t* pool = nostr_relay_pool_create(NULL);
    if (!pool) {
        printf("❌ Failed to create pool\n");
        return 1;
    }
    
    // Create a test event
    cJSON* event = cJSON_CreateObject();
    cJSON_AddStringToObject(event, "id", "test_event_12345");
    cJSON_AddNumberToObject(event, "kind", 1);
    cJSON_AddStringToObject(event, "content", "Test async publish");
    cJSON_AddNumberToObject(event, "created_at", time(NULL));
    cJSON_AddStringToObject(event, "pubkey", "test_pubkey");
    cJSON_AddStringToObject(event, "sig", "test_signature");
    
    // Test with non-existent relays (should trigger connection failure callbacks)
    const char* test_relays[] = {
        "ws://nonexistent1.example.com",
        "ws://nonexistent2.example.com"
    };
    int expected_callbacks = 2;
    
    printf("🚀 Testing async publish with connection failure callbacks...\n");
    
    // Call async publish
    int sent_count = nostr_relay_pool_publish_async(
        pool, test_relays, 2, event, test_callback, &expected_callbacks);
    
    printf("📊 Sent to %d relays\n", sent_count);
    
    // Wait a bit for callbacks (connection failures should be immediate)
    printf("⏳ Waiting for callbacks...\n");
    for (int i = 0; i < 10 && callback_count < expected_callbacks; i++) {
        nostr_relay_pool_poll(pool, 100);
        usleep(100000); // 100ms
    }
    
    printf("\n📈 Results:\n");
    printf("   Callbacks received: %d/%d\n", callback_count, expected_callbacks);
    printf("   Successful publishes: %d\n", success_count);
    
    // Test backward compatibility with synchronous version
    printf("\n🔄 Testing backward compatibility (sync version)...\n");
    int sync_result = nostr_relay_pool_publish_async(pool, test_relays, 2, event, NULL, NULL);
    printf("   Sync publish result: %d successful publishes\n", sync_result);
    
    // Cleanup
    cJSON_Delete(event);
    nostr_relay_pool_destroy(pool);
    
    printf("\n✅ Async publish test completed!\n");
    printf("   - Async callbacks: %s\n", callback_count >= expected_callbacks ? "PASS" : "FAIL");
    printf("   - Backward compatibility: %s\n", sync_result >= 0 ? "PASS" : "FAIL");
    
    return (callback_count >= expected_callbacks && sync_result >= 0) ? 0 : 1;
}