/*
 * NIP-44 Debug Test - Step-by-step comparison with nostr-tools vectors
 * 
 * This test prints intermediate values for comparison with nostr-tools
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "../nostr_core/nostr_core.h"

static int hex_to_bytes(const char* hex, unsigned char* bytes, size_t len) {
    if (strlen(hex) != len * 2) return -1;
    
    for (size_t i = 0; i < len; i++) {
        if (sscanf(hex + i * 2, "%2hhx", &bytes[i]) != 1) {
            return -1;
        }
    }
    return 0;
}

static void bytes_to_hex(const unsigned char* bytes, size_t len, char* hex) {
    for (size_t i = 0; i < len; i++) {
        sprintf(hex + i * 2, "%02x", bytes[i]);
    }
    hex[len * 2] = '\0';
}

// Test a specific vector from nostr-tools
static int test_vector_step_by_step(const char* name,
                                   const char* sec1_hex,
                                   const char* sec2_hex, 
                                   const char* expected_conversation_key_hex,
                                   const char* nonce_hex,
                                   const char* plaintext,
                                   const char* expected_payload) {
    
    printf("\n🔍 Testing Vector: %s\n", name);
    printf("=====================================\n");
    
    // Step 1: Parse keys
    unsigned char sec1[32], sec2[32];
    if (hex_to_bytes(sec1_hex, sec1, 32) != 0 || hex_to_bytes(sec2_hex, sec2, 32) != 0) {
        printf("❌ Failed to parse private keys\n");
        return -1;
    }
    
    printf("📝 sec1: %s\n", sec1_hex);
    printf("📝 sec2: %s\n", sec2_hex);
    
    // Step 2: Generate public keys
    unsigned char pub1[32], pub2[32];
    if (nostr_ec_public_key_from_private_key(sec1, pub1) != 0 ||
        nostr_ec_public_key_from_private_key(sec2, pub2) != 0) {
        printf("❌ Failed to derive public keys\n");
        return -1;
    }
    
    char pub1_hex[65], pub2_hex[65];
    bytes_to_hex(pub1, 32, pub1_hex);
    bytes_to_hex(pub2, 32, pub2_hex);
    printf("📝 pub1: %s\n", pub1_hex);
    printf("📝 pub2: %s\n", pub2_hex);
    
    // Step 3: Calculate ECDH shared secret (our raw implementation)
    unsigned char shared_secret[32];
    if (ecdh_shared_secret(sec1, pub2, shared_secret) != 0) {
        printf("❌ Failed to compute ECDH shared secret\n");
        return -1;
    }
    
    char shared_hex[65];
    bytes_to_hex(shared_secret, 32, shared_hex);
    printf("🔗 ECDH shared secret: %s\n", shared_hex);
    
    // Step 4: Calculate conversation key using HKDF-extract
    unsigned char conversation_key[32];
    const char* salt_str = "nip44-v2";
    if (nostr_hkdf_extract((const unsigned char*)salt_str, strlen(salt_str),
                          shared_secret, 32, conversation_key) != 0) {
        printf("❌ Failed to derive conversation key\n");
        return -1;
    }
    
    char conv_key_hex[65];
    bytes_to_hex(conversation_key, 32, conv_key_hex);
    printf("🗝️  Our conversation key: %s\n", conv_key_hex);
    printf("🎯 Expected conv key:    %s\n", expected_conversation_key_hex);
    
    if (strcmp(conv_key_hex, expected_conversation_key_hex) == 0) {
        printf("✅ Conversation key matches!\n");
    } else {
        printf("❌ Conversation key MISMATCH!\n");
        return -1;
    }
    
    // Step 5: Parse nonce
    unsigned char nonce[32];
    if (hex_to_bytes(nonce_hex, nonce, 32) != 0) {
        printf("❌ Failed to parse nonce\n");
        return -1;
    }
    printf("🎲 Nonce: %s\n", nonce_hex);
    
    // Step 6: Derive message keys using HKDF-expand
    unsigned char message_keys[76]; // 32 chacha_key + 12 chacha_nonce + 32 hmac_key
    if (nostr_hkdf_expand(conversation_key, 32, nonce, 32, message_keys, 76) != 0) {
        printf("❌ Failed to derive message keys\n");
        return -1;
    }
    
    char chacha_key_hex[65], chacha_nonce_hex[25], hmac_key_hex[65];
    bytes_to_hex(message_keys, 32, chacha_key_hex);
    bytes_to_hex(message_keys + 32, 12, chacha_nonce_hex);
    bytes_to_hex(message_keys + 44, 32, hmac_key_hex);
    
    printf("🔐 ChaCha key:   %s\n", chacha_key_hex);
    printf("🔐 ChaCha nonce: %s\n", chacha_nonce_hex);
    printf("🔐 HMAC key:     %s\n", hmac_key_hex);
    
    // Step 7: Test encryption with known nonce
    char our_payload[8192];
    int encrypt_result = nostr_nip44_encrypt_with_nonce(sec1, pub2, plaintext, nonce, our_payload, sizeof(our_payload));
    
    if (encrypt_result == NOSTR_SUCCESS) {
        printf("🔒 Our payload:       %s\n", our_payload);
        printf("🎯 Expected payload:  %s\n", expected_payload);
        
        if (strcmp(our_payload, expected_payload) == 0) {
            printf("✅ Payload matches perfectly!\n");
        } else {
            printf("❌ Payload MISMATCH!\n");
            
            // Try to decrypt expected payload with our conversation key
            printf("\n🔍 Debugging: Trying to decrypt expected payload...\n");
            char decrypted[8192];
            int decrypt_result = nostr_nip44_decrypt(sec2, pub1, expected_payload, decrypted, sizeof(decrypted));
            
            if (decrypt_result == NOSTR_SUCCESS) {
                printf("✅ Successfully decrypted expected payload!\n");
                printf("📝 Decrypted text: \"%s\"\n", decrypted);
                if (strcmp(decrypted, plaintext) == 0) {
                    printf("✅ Decrypted text matches original!\n");
                } else {
                    printf("❌ Decrypted text doesn't match original!\n");
                }
            } else {
                printf("❌ Failed to decrypt expected payload (error: %d)\n", decrypt_result);
            }
        }
    } else {
        printf("❌ Encryption failed with error: %d\n", encrypt_result);
        return -1;
    }
    
    return 0;
}

int main() {
    printf("🧪 NIP-44 Debug Test - Step-by-step Vector Comparison\n");
    printf("======================================================\n");
    
    // Initialize the library
    if (nostr_init() != NOSTR_SUCCESS) {
        printf("❌ Failed to initialize NOSTR library\n");
        return 1;
    }
    
    // Test the simple "a" vector
    test_vector_step_by_step(
        "Single char 'a'",
        "0000000000000000000000000000000000000000000000000000000000000001",
        "0000000000000000000000000000000000000000000000000000000000000002", 
        "c41c775356fd92eadc63ff5a0dc1da211b268cbea22316767095b2871ea1412d",
        "0000000000000000000000000000000000000000000000000000000000000001",
        "a",
        "AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABee0G5VSK0/9YypIObAtDKfYEAjD35uVkHyB0F4DwrcNaCXlCWZKaArsGrY6M9wnuTMxWfp1RTN9Xga8no+kF5Vsb"
    );
    
    // Test the emoji vector
    test_vector_step_by_step(
        "Emoji 🍕🫃",
        "0000000000000000000000000000000000000000000000000000000000000002",
        "0000000000000000000000000000000000000000000000000000000000000001",
        "c41c775356fd92eadc63ff5a0dc1da211b268cbea22316767095b2871ea1412d", 
        "f00000000000000000000000000000f00000000000000000000000000000000f",
        "🍕🫃",
        "AvAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAAAPSKSK6is9ngkX2+cSq85Th16oRTISAOfhStnixqZziKMDvB0QQzgFZdjLTPicCJaV8nDITO+QfaQ61+KbWQIOO2Yj"
    );
    
    // Test with get_message_keys test vector to verify HKDF-expand
    printf("\n🔍 Testing get_message_keys vector from nostr-tools:\n");
    printf("===========================================\n");
    
    unsigned char conv_key[32];
    if (hex_to_bytes("a1a3d60f3470a8612633924e91febf96dc5366ce130f658b1f0fc652c20b3b54", conv_key, 32) == 0) {
        unsigned char test_nonce[32];
        if (hex_to_bytes("e1e6f880560d6d149ed83dcc7e5861ee62a5ee051f7fde9975fe5d25d2a02d72", test_nonce, 32) == 0) {
            
            unsigned char message_keys[76];
            if (nostr_hkdf_expand(conv_key, 32, test_nonce, 32, message_keys, 76) == 0) {
                
                char chacha_key_hex[65], chacha_nonce_hex[25], hmac_key_hex[65];
                bytes_to_hex(message_keys, 32, chacha_key_hex);
                bytes_to_hex(message_keys + 32, 12, chacha_nonce_hex);
                bytes_to_hex(message_keys + 44, 32, hmac_key_hex);
                
                printf("📝 Conv key:      a1a3d60f3470a8612633924e91febf96dc5366ce130f658b1f0fc652c20b3b54\n");
                printf("📝 Nonce:         e1e6f880560d6d149ed83dcc7e5861ee62a5ee051f7fde9975fe5d25d2a02d72\n");
                printf("🔐 Our ChaCha key:     %s\n", chacha_key_hex);
                printf("🎯 Expected ChaCha key: f145f3bed47cb70dbeaac07f3a3fe683e822b3715edb7c4fe310829014ce7d76\n");
                printf("🔐 Our ChaCha nonce:   %s\n", chacha_nonce_hex);
                printf("🎯 Expected ChaCha nonce: c4ad129bb01180c0933a160c\n");
                printf("🔐 Our HMAC key:       %s\n", hmac_key_hex);
                printf("🎯 Expected HMAC key:   027c1db445f05e2eee864a0975b0ddef5b7110583c8c192de3732571ca5838c4\n");
                
                if (strcmp(chacha_key_hex, "f145f3bed47cb70dbeaac07f3a3fe683e822b3715edb7c4fe310829014ce7d76") == 0) {
                    printf("✅ ChaCha key matches!\n");
                } else {
                    printf("❌ ChaCha key MISMATCH!\n");
                }
                
                if (strcmp(chacha_nonce_hex, "c4ad129bb01180c0933a160c") == 0) {
                    printf("✅ ChaCha nonce matches!\n");
                } else {
                    printf("❌ ChaCha nonce MISMATCH!\n");
                }
                
                if (strcmp(hmac_key_hex, "027c1db445f05e2eee864a0975b0ddef5b7110583c8c192de3732571ca5838c4") == 0) {
                    printf("✅ HMAC key matches!\n");
                } else {
                    printf("❌ HMAC key MISMATCH!\n");
                }
            } else {
                printf("❌ Failed to expand message keys\n");
            }
        } else {
            printf("❌ Failed to parse test nonce\n");
        }
    } else {
        printf("❌ Failed to parse conversation key\n");
    }
    
    nostr_cleanup();
    printf("\n🏁 Debug test completed\n");
    return 0;
}
