/*
 * NIP-42 Authentication of Clients to Relays Test Suite
 * Tests auth challenge generation, event creation, validation, and message parsing
 * Following TESTS POLICY: Shows expected vs actual values, prints entire JSON events
 */

#define _GNU_SOURCE  // For strdup on Linux
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "../nostr_core/nip042.h"
#include "../nostr_core/nip001.h"
#include "../nostr_core/nostr_common.h"
#include "../nostr_core/utils.h"
#include "../cjson/cJSON.h"

// Ensure strdup is declared
#ifndef strdup
extern char *strdup(const char *s);
#endif

// Test counter for tracking progress
static int test_count = 0;
static int passed_tests = 0;

void print_test_header(const char* test_name) {
    test_count++;
    printf("\n=== TEST %d: %s ===\n", test_count, test_name);
}

void print_test_result(int passed, const char* test_name) {
    if (passed) {
        passed_tests++;
        printf("✅ PASS: %s\n", test_name);
    } else {
        printf("❌ FAIL: %s\n", test_name);
    }
}

void print_json_comparison(const char* label, cJSON* expected, cJSON* actual) {
    char* expected_str = cJSON_Print(expected);
    char* actual_str;
    
    if (actual) {
        actual_str = cJSON_Print(actual);
    } else {
        actual_str = strdup("NULL");
    }
    
    printf("%s Expected JSON:\n%s\n", label, expected_str ? expected_str : "NULL");
    printf("%s Actual JSON:\n%s\n", label, actual_str ? actual_str : "NULL");
    
    if (expected_str) free(expected_str);
    if (actual_str) free(actual_str);
}

// Test 1: Challenge generation
int test_challenge_generation(void) {
    print_test_header("Challenge Generation");
    
    nostr_auth_challenge_t challenge1, challenge2;
    
    printf("Generating first challenge...\n");
    int result1 = nostr_nip42_generate_challenge(challenge1.challenge, NOSTR_NIP42_DEFAULT_CHALLENGE_LENGTH);
    printf("Result: %d (%s)\n", result1, nostr_strerror(result1));
    
    if (result1 != NOSTR_SUCCESS) {
        printf("❌ Failed to generate first challenge\n");
        return 0;
    }
    
    printf("First challenge: %s\n", challenge1.challenge);
    printf("Challenge length: %lu\n", strlen(challenge1.challenge));
    printf("Expected length: %d\n", NOSTR_NIP42_DEFAULT_CHALLENGE_LENGTH * 2);
    
    if (strlen(challenge1.challenge) != NOSTR_NIP42_DEFAULT_CHALLENGE_LENGTH * 2) {
        printf("❌ Challenge length incorrect\n");
        return 0;
    }
    
    printf("Generating second challenge...\n");
    int result2 = nostr_nip42_generate_challenge(challenge2.challenge, NOSTR_NIP42_DEFAULT_CHALLENGE_LENGTH);
    printf("Result: %d (%s)\n", result2, nostr_strerror(result2));
    
    if (result2 != NOSTR_SUCCESS) {
        printf("❌ Failed to generate second challenge\n");
        return 0;
    }
    
    printf("Second challenge: %s\n", challenge2.challenge);
    
    // Challenges should be different (extremely high probability)
    if (strcmp(challenge1.challenge, challenge2.challenge) == 0) {
        printf("❌ Two challenges are identical (highly unlikely)\n");
        return 0;
    }
    
    printf("✅ Challenges are different (good entropy)\n");
    return 1;
}

// Test 2: AUTH message creation (server-side challenge)
int test_auth_message_creation(void) {
    print_test_header("AUTH Message Creation - Server Challenge");
    
    nostr_auth_challenge_t challenge;
    int gen_result = nostr_nip42_generate_challenge(challenge.challenge, NOSTR_NIP42_DEFAULT_CHALLENGE_LENGTH);
    
    if (gen_result != NOSTR_SUCCESS) {
        printf("❌ Failed to generate challenge for message test\n");
        return 0;
    }
    
    printf("Generated challenge: %s\n", challenge.challenge);
    
    // Create AUTH challenge message: ["AUTH", "challenge_string"]
    cJSON* message_array = cJSON_CreateArray();
    if (!message_array) {
        printf("❌ Failed to create message array\n");
        return 0;
    }
    
    cJSON_AddItemToArray(message_array, cJSON_CreateString("AUTH"));
    cJSON_AddItemToArray(message_array, cJSON_CreateString(challenge.challenge));
    
    char* auth_message = cJSON_PrintUnformatted(message_array);
    cJSON_Delete(message_array);
    
    if (!auth_message) {
        printf("❌ Failed to create AUTH message\n");
        return 0;
    }
    
    int result = NOSTR_SUCCESS;
    
    printf("Message creation result: %d (%s)\n", result, nostr_strerror(result));
    printf("AUTH message: %s\n", auth_message);
    
    // Parse the message to verify format
    cJSON* parsed = cJSON_Parse(auth_message);
    if (!parsed) {
        printf("❌ AUTH message is not valid JSON\n");
        return 0;
    }
    
    // Check if it's an array with 2 elements
    if (!cJSON_IsArray(parsed) || cJSON_GetArraySize(parsed) != 2) {
        printf("❌ AUTH message is not a 2-element array\n");
        cJSON_Delete(parsed);
        return 0;
    }
    
    // Check first element is "AUTH"
    cJSON* first = cJSON_GetArrayItem(parsed, 0);
    if (!cJSON_IsString(first) || strcmp(cJSON_GetStringValue(first), "AUTH") != 0) {
        printf("❌ First element is not 'AUTH'\n");
        cJSON_Delete(parsed);
        return 0;
    }
    
    // Check second element is our challenge string
    cJSON* second = cJSON_GetArrayItem(parsed, 1);
    if (!cJSON_IsString(second) || strcmp(cJSON_GetStringValue(second), challenge.challenge) != 0) {
        printf("❌ Second element is not our challenge string\n");
        printf("Expected: %s\n", challenge.challenge);
        printf("Actual: %s\n", cJSON_GetStringValue(second));
        cJSON_Delete(parsed);
        free(auth_message);
        return 0;
    }
    
    printf("✅ AUTH challenge message format is correct\n");
    cJSON_Delete(parsed);
    free(auth_message);
    return 1;
}

// Test 3: Authentication event creation (client-side)
int test_auth_event_creation(void) {
    print_test_header("Authentication Event Creation - Client Side");
    
    const char* private_key_hex = "91ba716fa9e7ea2fcbad360cf4f8e0d312f73984da63d90f524ad61a6a1e7dbe";
    const char* relay_url = "wss://relay.example.com";
    const char* challenge_string = "test_challenge_12345678901234567890123456789012";
    
    unsigned char private_key[32];
    nostr_hex_to_bytes(private_key_hex, private_key, 32);
    
    printf("Private key (hex): %s\n", private_key_hex);
    printf("Relay URL: %s\n", relay_url);
    printf("Challenge: %s\n", challenge_string);
    
    cJSON* auth_event = nostr_nip42_create_auth_event(challenge_string, relay_url, private_key, 0);
    
    if (!auth_event) {
        printf("❌ Failed to create authentication event\n");
        return 0;
    }
    
    char* event_str = cJSON_Print(auth_event);
    printf("Created Auth Event JSON:\n%s\n", event_str);
    free(event_str);
    
    // Validate the event structure
    int structure_result = nostr_validate_event_structure(auth_event);
    printf("Structure validation result: %d (%s)\n", structure_result, nostr_strerror(structure_result));
    
    if (structure_result != NOSTR_SUCCESS) {
        printf("❌ Auth event failed structure validation\n");
        cJSON_Delete(auth_event);
        return 0;
    }
    
    // Validate the event signature
    int crypto_result = nostr_verify_event_signature(auth_event);
    printf("Signature validation result: %d (%s)\n", crypto_result, nostr_strerror(crypto_result));
    
    if (crypto_result != NOSTR_SUCCESS) {
        printf("❌ Auth event failed signature validation\n");
        cJSON_Delete(auth_event);
        return 0;
    }
    
    // Check kind is 22242
    cJSON* kind = cJSON_GetObjectItem(auth_event, "kind");
    if (!cJSON_IsNumber(kind) || cJSON_GetNumberValue(kind) != 22242) {
        printf("❌ Auth event kind is not 22242\n");
        cJSON_Delete(auth_event);
        return 0;
    }
    
    // Check for relay tag
    cJSON* tags = cJSON_GetObjectItem(auth_event, "tags");
    int found_relay = 0, found_challenge = 0;
    
    if (cJSON_IsArray(tags)) {
        cJSON* tag = NULL;
        cJSON_ArrayForEach(tag, tags) {
            if (cJSON_IsArray(tag) && cJSON_GetArraySize(tag) >= 2) {
                cJSON* tag_name = cJSON_GetArrayItem(tag, 0);
                cJSON* tag_value = cJSON_GetArrayItem(tag, 1);
                
                if (cJSON_IsString(tag_name) && cJSON_IsString(tag_value)) {
                    if (strcmp(cJSON_GetStringValue(tag_name), "relay") == 0) {
                        found_relay = 1;
                        if (strcmp(cJSON_GetStringValue(tag_value), relay_url) != 0) {
                            printf("❌ Relay tag value incorrect\n");
                            printf("Expected: %s\n", relay_url);
                            printf("Actual: %s\n", cJSON_GetStringValue(tag_value));
                            cJSON_Delete(auth_event);
                            return 0;
                        }
                    } else if (strcmp(cJSON_GetStringValue(tag_name), "challenge") == 0) {
                        found_challenge = 1;
                        if (strcmp(cJSON_GetStringValue(tag_value), challenge_string) != 0) {
                            printf("❌ Challenge tag value incorrect\n");
                            printf("Expected: %s\n", challenge_string);
                            printf("Actual: %s\n", cJSON_GetStringValue(tag_value));
                            cJSON_Delete(auth_event);
                            return 0;
                        }
                    }
                }
            }
        }
    }
    
    if (!found_relay) {
        printf("❌ Missing relay tag\n");
        cJSON_Delete(auth_event);
        return 0;
    }
    
    if (!found_challenge) {
        printf("❌ Missing challenge tag\n");
        cJSON_Delete(auth_event);
        return 0;
    }
    
    printf("✅ Authentication event created successfully with correct tags\n");
    cJSON_Delete(auth_event);
    return 1;
}

// Test 4: Authentication event validation (server-side)
int test_auth_event_validation(void) {
    print_test_header("Authentication Event Validation - Server Side");
    
    // Create a valid auth event first
    const char* private_key_hex = "91ba716fa9e7ea2fcbad360cf4f8e0d312f73984da63d90f524ad61a6a1e7dbe";
    const char* relay_url = "wss://relay.example.com";
    const char* challenge_string = "validation_challenge_1234567890123456789012";
    
    unsigned char private_key[32];
    nostr_hex_to_bytes(private_key_hex, private_key, 32);
    
    cJSON* auth_event = nostr_nip42_create_auth_event(challenge_string, relay_url, private_key, 0);
    
    if (!auth_event) {
        printf("❌ Failed to create auth event for validation test\n");
        return 0;
    }
    
    char* event_str = cJSON_Print(auth_event);
    printf("Auth Event to validate:\n%s\n", event_str);
    free(event_str);
    
    // Test successful validation
    printf("Testing successful validation...\n");
    int result = nostr_nip42_verify_auth_event(auth_event, challenge_string, relay_url, 0);
    printf("Validation result: %d (%s)\n", result, nostr_strerror(result));
    
    if (result != NOSTR_SUCCESS) {
        printf("❌ Valid auth event failed validation\n");
        cJSON_Delete(auth_event);
        return 0;
    }
    printf("✅ Valid auth event passed validation\n");
    
    // Test wrong relay URL
    printf("\nTesting wrong relay URL...\n");
    result = nostr_nip42_verify_auth_event(auth_event, challenge_string, "wss://wrong.relay.com", 0);
    printf("Expected: NOSTR_ERROR_NIP42_URL_MISMATCH (-206)\n");
    printf("Actual: %d (%s)\n", result, nostr_strerror(result));
    
    if (result != NOSTR_ERROR_NIP42_URL_MISMATCH) {
        printf("❌ Wrong relay validation didn't fail correctly\n");
        cJSON_Delete(auth_event);
        return 0;
    }
    printf("✅ Wrong relay URL correctly rejected\n");
    
    // Test wrong challenge
    printf("\nTesting wrong challenge...\n");
    result = nostr_nip42_verify_auth_event(auth_event, "wrong_challenge_string_here", relay_url, 0);
    printf("Expected: NOSTR_ERROR_NIP42_INVALID_CHALLENGE (-203)\n");
    printf("Actual: %d (%s)\n", result, nostr_strerror(result));
    
    if (result != NOSTR_ERROR_NIP42_INVALID_CHALLENGE) {
        printf("❌ Wrong challenge validation didn't fail correctly\n");
        cJSON_Delete(auth_event);
        return 0;
    }
    printf("✅ Wrong challenge correctly rejected\n");
    
    cJSON_Delete(auth_event);
    return 1;
}

// Test 5: AUTH message parsing (client-side)
int test_auth_message_parsing(void) {
    print_test_header("AUTH Message Parsing - Client Side");
    
    // Test parsing challenge message
    const char* challenge_msg = "[\"AUTH\", \"test_challenge_from_server_123456789012\"]";
    printf("Parsing AUTH challenge message: %s\n", challenge_msg);
    
    char extracted_challenge[NOSTR_NIP42_MAX_CHALLENGE_LENGTH];
    int result = nostr_nip42_parse_auth_challenge(challenge_msg, extracted_challenge, sizeof(extracted_challenge));
    
    printf("Parse result: %d (%s)\n", result, nostr_strerror(result));
    printf("Expected challenge: test_challenge_from_server_123456789012\n");
    printf("Extracted challenge: %s\n", extracted_challenge);
    
    if (result != NOSTR_SUCCESS) {
        printf("❌ Failed to parse valid AUTH message\n");
        return 0;
    }
    
    if (strcmp(extracted_challenge, "test_challenge_from_server_123456789012") != 0) {
        printf("❌ Extracted challenge doesn't match expected\n");
        return 0;
    }
    printf("✅ AUTH challenge message parsed correctly\n");
    
    // Test invalid message format
    printf("\nTesting invalid message format...\n");
    const char* invalid_msg = "[\"WRONG\", \"challenge\"]";
    result = nostr_nip42_parse_auth_challenge(invalid_msg, extracted_challenge, sizeof(extracted_challenge));
    
    printf("Parse result: %d (%s)\n", result, nostr_strerror(result));
    printf("Expected: NOSTR_ERROR_NIP42_INVALID_MESSAGE_FORMAT (-205)\n");
    
    if (result != NOSTR_ERROR_NIP42_INVALID_MESSAGE_FORMAT) {
        printf("❌ Invalid message format should have failed\n");
        return 0;
    }
    printf("✅ Invalid message format correctly rejected\n");
    
    return 1;
}

// Test 6: AUTH response message creation (client-side)
int test_auth_response_creation(void) {
    print_test_header("AUTH Response Message Creation - Client Side");
    
    // Create an auth event first
    const char* private_key_hex = "91ba716fa9e7ea2fcbad360cf4f8e0d312f73984da63d90f524ad61a6a1e7dbe";
    const char* relay_url = "wss://relay.example.com";
    const char* challenge_string = "response_test_challenge_1234567890123456";
    
    unsigned char private_key[32];
    nostr_hex_to_bytes(private_key_hex, private_key, 32);
    
    cJSON* auth_event = nostr_nip42_create_auth_event(challenge_string, relay_url, private_key, 0);
    
    if (!auth_event) {
        printf("❌ Failed to create auth event for response test\n");
        return 0;
    }
    
    char* auth_response = nostr_nip42_create_auth_message(auth_event);
    int result = auth_response ? NOSTR_SUCCESS : NOSTR_ERROR_MEMORY_FAILED;
    
    printf("Response creation result: %d (%s)\n", result, nostr_strerror(result));
    printf("AUTH response message: %s\n", auth_response ? auth_response : "NULL");
    
    if (result != NOSTR_SUCCESS) {
        printf("❌ Failed to create AUTH response message\n");
        cJSON_Delete(auth_event);
        return 0;
    }
    
    // Parse and validate the response format
    cJSON* parsed = cJSON_Parse(auth_response);
    if (!parsed) {
        printf("❌ AUTH response is not valid JSON\n");
        cJSON_Delete(auth_event);
        return 0;
    }
    
    // Should be ["AUTH", <event-json>]
    if (!cJSON_IsArray(parsed) || cJSON_GetArraySize(parsed) != 2) {
        printf("❌ AUTH response is not a 2-element array\n");
        cJSON_Delete(parsed);
        cJSON_Delete(auth_event);
        return 0;
    }
    
    cJSON* first = cJSON_GetArrayItem(parsed, 0);
    if (!cJSON_IsString(first) || strcmp(cJSON_GetStringValue(first), "AUTH") != 0) {
        printf("❌ First element is not 'AUTH'\n");
        cJSON_Delete(parsed);
        cJSON_Delete(auth_event);
        return 0;
    }
    
    cJSON* second = cJSON_GetArrayItem(parsed, 1);
    if (!cJSON_IsObject(second)) {
        printf("❌ Second element is not an object (event)\n");
        cJSON_Delete(parsed);
        cJSON_Delete(auth_event);
        return 0;
    }
    
    // Check if the event in the response matches our created event
    cJSON* response_kind = cJSON_GetObjectItem(second, "kind");
    if (!cJSON_IsNumber(response_kind) || cJSON_GetNumberValue(response_kind) != 22242) {
        printf("❌ Response event kind is not 22242\n");
        cJSON_Delete(parsed);
        cJSON_Delete(auth_event);
        return 0;
    }
    
    printf("✅ AUTH response message format is correct\n");
    cJSON_Delete(parsed);
    cJSON_Delete(auth_event);
    free(auth_response);
    return 1;
}

// Test 7: Error conditions and edge cases
int test_error_conditions(void) {
    print_test_header("Error Conditions and Edge Cases");
    
    int all_passed = 1;
    
    // Test 1: NULL parameters
    printf("\nSubtest 1: NULL parameters\n");
    int result = nostr_nip42_generate_challenge(NULL, 32);
    printf("Expected: NOSTR_ERROR_INVALID_INPUT (-1)\n");
    printf("Actual: %d (%s)\n", result, nostr_strerror(result));
    if (result != NOSTR_ERROR_INVALID_INPUT) all_passed = 0;
    
    // Test 2: Invalid challenge length
    printf("\nSubtest 2: Invalid challenge in validation\n");
    const char* private_key_hex = "91ba716fa9e7ea2fcbad360cf4f8e0d312f73984da63d90f524ad61a6a1e7dbe";
    const char* relay_url = "wss://relay.example.com";
    const char* valid_challenge = "valid_challenge_1234567890123456789012345";
    
    unsigned char private_key[32];
    nostr_hex_to_bytes(private_key_hex, private_key, 32);
    
    cJSON* auth_event = nostr_nip42_create_auth_event(valid_challenge, relay_url, private_key, 0);
    if (auth_event) {
        result = nostr_nip42_verify_auth_event(auth_event, "short", relay_url, 0);  // Too short
        printf("Expected: NOSTR_ERROR_NIP42_INVALID_CHALLENGE (-203)\n");
        printf("Actual: %d (%s)\n", result, nostr_strerror(result));
        if (result != NOSTR_ERROR_NIP42_INVALID_CHALLENGE) all_passed = 0;
        cJSON_Delete(auth_event);
    } else {
        printf("❌ Failed to create auth event for validation test\n");
        all_passed = 0;
    }
    
    // Test 3: Invalid JSON parsing
    printf("\nSubtest 3: Invalid JSON in message parsing\n");
    char challenge_buffer[NOSTR_NIP42_MAX_CHALLENGE_LENGTH];
    result = nostr_nip42_parse_auth_challenge("invalid json", challenge_buffer, sizeof(challenge_buffer));
    printf("Expected: NOSTR_ERROR_NIP42_INVALID_MESSAGE_FORMAT (-205)\n");
    printf("Actual: %d (%s)\n", result, nostr_strerror(result));
    if (result != NOSTR_ERROR_NIP42_INVALID_MESSAGE_FORMAT) all_passed = 0;
    
    // Test 4: Wrong array size
    printf("\nSubtest 4: Wrong array size in message parsing\n");
    result = nostr_nip42_parse_auth_challenge("[\"AUTH\"]", challenge_buffer, sizeof(challenge_buffer));  // Only 1 element
    printf("Expected: NOSTR_ERROR_NIP42_INVALID_MESSAGE_FORMAT (-205)\n");
    printf("Actual: %d (%s)\n", result, nostr_strerror(result));
    if (result != NOSTR_ERROR_NIP42_INVALID_MESSAGE_FORMAT) all_passed = 0;
    
    return all_passed;
}

// Test 8: Full authentication flow simulation
int test_full_auth_flow(void) {
    print_test_header("Full Authentication Flow Simulation");
    
    const char* private_key_hex = "91ba716fa9e7ea2fcbad360cf4f8e0d312f73984da63d90f524ad61a6a1e7dbe";
    const char* relay_url = "wss://test-relay.nostr.com";
    
    unsigned char private_key[32];
    nostr_hex_to_bytes(private_key_hex, private_key, 32);
    
    printf("=== STEP 1: Server generates challenge ===\n");
    nostr_auth_challenge_t challenge;
    int result = nostr_nip42_generate_challenge(challenge.challenge, NOSTR_NIP42_DEFAULT_CHALLENGE_LENGTH);
    if (result != NOSTR_SUCCESS) {
        printf("❌ Failed to generate challenge\n");
        return 0;
    }
    printf("Generated challenge: %s\n", challenge.challenge);
    
    printf("\n=== STEP 2: Server sends AUTH message ===\n");
    cJSON* message_array = cJSON_CreateArray();
    cJSON_AddItemToArray(message_array, cJSON_CreateString("AUTH"));
    cJSON_AddItemToArray(message_array, cJSON_CreateString(challenge.challenge));
    char* auth_message = cJSON_PrintUnformatted(message_array);
    cJSON_Delete(message_array);
    
    if (!auth_message) {
        printf("❌ Failed to create AUTH message\n");
        return 0;
    }
    printf("Server sends: %s\n", auth_message);
    
    printf("\n=== STEP 3: Client parses AUTH message ===\n");
    char parsed_challenge[NOSTR_NIP42_MAX_CHALLENGE_LENGTH];
    result = nostr_nip42_parse_auth_challenge(auth_message, parsed_challenge, sizeof(parsed_challenge));
    if (result != NOSTR_SUCCESS) {
        printf("❌ Failed to parse AUTH message\n");
        free(auth_message);
        return 0;
    }
    printf("Client extracted challenge: %s\n", parsed_challenge);
    
    if (strcmp(challenge.challenge, parsed_challenge) != 0) {
        printf("❌ Parsed challenge doesn't match original\n");
        free(auth_message);
        return 0;
    }
    
    printf("\n=== STEP 4: Client creates auth event ===\n");
    cJSON* auth_event = nostr_nip42_create_auth_event(parsed_challenge, relay_url, private_key, 0);
    if (!auth_event) {
        printf("❌ Failed to create auth event\n");
        return 0;
    }
    
    char* event_str = cJSON_Print(auth_event);
    printf("Client created auth event:\n%s\n", event_str);
    free(event_str);
    
    printf("\n=== STEP 5: Client sends AUTH response ===\n");
    char* auth_response = nostr_nip42_create_auth_message(auth_event);
    if (!auth_response) {
        printf("❌ Failed to create AUTH response\n");
        cJSON_Delete(auth_event);
        free(auth_message);
        return 0;
    }
    printf("Client sends: %s\n", auth_response);
    
    printf("\n=== STEP 6: Server validates auth event ===\n");
    result = nostr_nip42_verify_auth_event(auth_event, challenge.challenge, relay_url, 0);
    printf("Server validation result: %d (%s)\n", result, nostr_strerror(result));
    
    if (result != NOSTR_SUCCESS) {
        printf("❌ Server validation failed\n");
        cJSON_Delete(auth_event);
        free(auth_message);
        free(auth_response);
        return 0;
    }
    
    printf("✅ FULL AUTHENTICATION FLOW COMPLETED SUCCESSFULLY!\n");
    printf("✅ Challenge generated -> Message sent -> Challenge parsed -> Event created -> Response sent -> Event validated\n");
    
    cJSON_Delete(auth_event);
    free(auth_message);
    free(auth_response);
    return 1;
}

int main(void) {
    printf("=== NIP-42 Authentication of Clients to Relays Test Suite ===\n");
    printf("Following TESTS POLICY: Shows expected vs actual values, prints entire JSON events\n");
    printf("Tests both client-side and server-side authentication functionality\n");
    
    // Initialize crypto library
    if (nostr_init() != NOSTR_SUCCESS) {
        printf("❌ Failed to initialize nostr library\n");
        return 1;
    }
    
    int all_passed = 1;
    int test_result;
    
    // Test 1: Challenge generation
    test_result = test_challenge_generation();
    print_test_result(test_result, "Challenge Generation");
    if (!test_result) all_passed = 0;
    
    // Test 2: AUTH message creation
    test_result = test_auth_message_creation();
    print_test_result(test_result, "AUTH Message Creation - Server Challenge");
    if (!test_result) all_passed = 0;
    
    // Test 3: Auth event creation
    test_result = test_auth_event_creation();
    print_test_result(test_result, "Authentication Event Creation - Client Side");
    if (!test_result) all_passed = 0;
    
    // Test 4: Auth event validation
    test_result = test_auth_event_validation();
    print_test_result(test_result, "Authentication Event Validation - Server Side");
    if (!test_result) all_passed = 0;
    
    // Test 5: AUTH message parsing
    test_result = test_auth_message_parsing();
    print_test_result(test_result, "AUTH Message Parsing - Client Side");
    if (!test_result) all_passed = 0;
    
    // Test 6: AUTH response creation
    test_result = test_auth_response_creation();
    print_test_result(test_result, "AUTH Response Message Creation - Client Side");
    if (!test_result) all_passed = 0;
    
    // Test 7: Error conditions
    test_result = test_error_conditions();
    print_test_result(test_result, "Error Conditions and Edge Cases");
    if (!test_result) all_passed = 0;
    
    // Test 8: Full authentication flow
    test_result = test_full_auth_flow();
    print_test_result(test_result, "Full Authentication Flow Simulation");
    if (!test_result) all_passed = 0;
    
    // Summary
    printf("\n=== TEST SUMMARY ===\n");
    printf("Total tests: %d\n", test_count);
    printf("Passed: %d\n", passed_tests);
    printf("Failed: %d\n", test_count - passed_tests);
    
    if (all_passed) {
        printf("🎉 ALL TESTS PASSED! NIP-42 Authentication implementation is working correctly.\n");
        printf("✅ Challenge generation works\n");
        printf("✅ AUTH message creation/parsing works\n");
        printf("✅ Authentication event creation works\n");
        printf("✅ Authentication event validation works\n");
        printf("✅ Full authentication flow works\n");
        printf("✅ Error handling works\n");
    } else {
        printf("❌ SOME TESTS FAILED. Please review the output above.\n");
    }
    
    nostr_cleanup();
    return all_passed ? 0 : 1;
}