/**
 * JavaScript Mix Payloads Sender Test
 * Tests the smartsend function with mixed payload types
 * 
 * This test mirrors test_julia_mix_payloads_sender.jl and demonstrates that
 * any combination and any number of mixed content can be sent correctly.
 */

const NATSBridge = require('../src/natsbridge.js');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');

const TEST_SUBJECT = '/natsbridge';
const TEST_BROKER_URL = process.env.NATS_URL || 'nats.yiem.cc';
const TEST_FILESERVER_URL = process.env.FILESERVER_URL || 'http://192.168.88.104:8080';
const SIZE_THRESHOLD = 1_000_000; // 1MB threshold

async function runTest() {
    console.log('=== JavaScript Mix Payloads Sender Test ===\n');
    
    const correlationId = crypto.randomUUID();
    console.log(`Correlation ID: ${correlationId}`);
    console.log(`Subject: ${TEST_SUBJECT}`);
    console.log(`Broker URL: ${TEST_BROKER_URL}`);
    console.log(`Fileserver URL: ${TEST_FILESERVER_URL}`);
    console.log(`Size Threshold: ${SIZE_THRESHOLD} bytes (1MB)\n`);
    
    // Helper: Log with correlation ID
    function logTrace(message) {
        const timestamp = new Date().toISOString();
        console.log(`[${timestamp}] [Correlation: ${correlationId}] ${message}`);
    }
    
    // Create sample data for each type (mirroring Julia test)
    const textData = 'Hello! This is a test chat message. 🎉\nHow are you doing today? 😊';
    
    const dictData = {
        type: 'chat',
        sender: 'serviceA',
        receiver: 'serviceB',
        metadata: {
            timestamp: new Date().toISOString(),
            priority: 'high',
            tags: ['urgent', 'chat', 'test']
        },
        content: {
            text: 'This is a JSON-formatted chat message with nested structure.',
            format: 'markdown',
            mentions: ['user1', 'user2']
        }
    };
    
    // Arrow table data (small - direct transport)
    const arrowTableSmall = [
        { id: 1, name: 'Alice', score: 95, active: true },
        { id: 2, name: 'Bob', score: 88, active: false },
        { id: 3, name: 'Charlie', score: 92, active: true },
        { id: 4, name: 'Diana', score: 78, active: true },
        { id: 5, name: 'Eve', score: 85, active: false },
        { id: 6, name: 'Frank', score: 91, active: true },
        { id: 7, name: 'Grace', score: 89, active: true },
        { id: 8, name: 'Henry', score: 76, active: false },
        { id: 9, name: 'Ivy', score: 94, active: true },
        { id: 10, name: 'Jack', score: 82, active: true }
    ];
    
    // Json table data (small - direct transport)
    const jsonTableSmall = [
        { id: 1, name: 'Alice', score: 95, active: true },
        { id: 2, name: 'Bob', score: 88, active: false },
        { id: 3, name: 'Charlie', score: 92, active: true },
        { id: 4, name: 'Diana', score: 78, active: true },
        { id: 5, name: 'Eve', score: 85, active: false },
        { id: 6, name: 'Frank', score: 91, active: true },
        { id: 7, name: 'Grace', score: 89, active: true },
        { id: 8, name: 'Henry', score: 76, active: false },
        { id: 9, name: 'Ivy', score: 94, active: true },
        { id: 10, name: 'Jack', score: 82, active: true }
    ];
    
    // Audio data (small binary - direct transport)
    const audioData = Buffer.alloc(100);
    for (let i = 0; i < 100; i++) {
        audioData[i] = Math.floor(Math.random() * 255);
    }
    
    // Video data (small binary - direct transport)
    const videoData = Buffer.alloc(150);
    for (let i = 0; i < 150; i++) {
        videoData[i] = Math.floor(Math.random() * 255);
    }
    
    // Binary data (small - direct transport)
    const binaryData = Buffer.alloc(200);
    for (let i = 0; i < 200; i++) {
        binaryData[i] = Math.floor(Math.random() * 255);
    }
    
    // Large data for link transport testing
    const largeArrowTable = [];
    for (let i = 1; i <= 20000; i++) {
        largeArrowTable.push({
            id: i,
            name: `user_${i}`,
            score: Math.floor(Math.random() * 51) + 50,
            active: Math.random() > 0.5,
            timestamp: new Date().toISOString()
        });
    }
    
    const largeJsonTable = [];
    for (let i = 1; i <= 50000; i++) {
        largeJsonTable.push({
            id: i,
            name: `user_${i}`,
            score: Math.floor(Math.random() * 51) + 50,
            active: Math.random() > 0.5
        });
    }
    
    const largeAudioData = Buffer.alloc(1_500_000);
    for (let i = 0; i < 1_500_000; i++) {
        largeAudioData[i] = Math.floor(Math.random() * 255);
    }
    
    const largeVideoData = Buffer.alloc(1_500_000);
    for (let i = 0; i < 1_500_000; i++) {
        largeVideoData[i] = Math.floor(Math.random() * 255);
    }
    
    const largeBinaryData = Buffer.alloc(1_500_000);
    for (let i = 0; i < 1_500_000; i++) {
        largeBinaryData[i] = Math.floor(Math.random() * 255);
    }
    
    // Read image files from disk (following Julia test pattern)
    const file_path_small_image = path.join(__dirname, 'small_image.jpg');
    const file_data_small_image = fs.readFileSync(file_path_small_image);
    const filename_small_image = path.basename(file_path_small_image);
    
    const file_path_large_image = path.join(__dirname, 'large_image.png');
    const file_data_large_image = fs.readFileSync(file_path_large_image);
    const filename_large_image = path.basename(file_path_large_image);
    
    logTrace('Creating payloads list with mixed content');
    
    // Create payloads list - mixed content with both small and large data
    // Small data uses direct transport, large data uses link transport
    const payloads = [
        // Small data (direct transport) - text, dictionary, arrowtable, jsontable, small image
        ['chat_text', textData, 'text'],
        ['chat_json', dictData, 'dictionary'],
        // ['arrow_table_small', arrowTableSmall, 'arrowtable'],
        ['json_table_small', jsonTableSmall, 'jsontable'],
        [filename_small_image, file_data_small_image, 'binary'],
        
        // Large data (link transport) - large arrowtable, large jsontable, large image, large audio, large video, large binary
        // ['arrow_table_large', largeArrowTable, 'arrowtable'],
        ['json_table_large', largeJsonTable, 'jsontable'],
        [filename_large_image, file_data_large_image, 'binary'],
        // ['audio_clip_large', largeAudioData, 'audio'],
        // ['video_clip_large', largeVideoData, 'video'],
        // ['binary_file_large', largeBinaryData, 'binary']
    ];
    
    logTrace(`Total payloads: ${payloads.length}`);
    
    try {
        // Send the message
        console.log('Sending mixed payloads...\n');
        const [env, envJsonStr] = await NATSBridge.smartsend(
            TEST_SUBJECT,
            payloads,
            {
                broker_url: TEST_BROKER_URL,
                fileserver_url: TEST_FILESERVER_URL,
                fileserver_upload_handler: NATSBridge.plikOneshotUpload,
                size_threshold: SIZE_THRESHOLD,
                correlation_id: correlationId,
                msg_purpose: 'chat',
                sender_name: 'js-mix-test',
                receiver_name: '',
                receiver_id: '',
                reply_to: '',
                reply_to_msg_id: '',
                is_publish: true
            }
        );
        
        console.log('\n=== Envelope Created ===');
        console.log(`Correlation ID: ${env.correlation_id}`);
        console.log(`Message ID: ${env.msg_id}`);
        console.log(`Timestamp: ${env.timestamp}`);
        console.log(`Subject: ${env.send_to}`);
        console.log(`Purpose: ${env.msg_purpose}`);
        console.log(`Sender: ${env.sender_name}`);
        console.log(`Payloads: ${env.payloads.length}\n`);
        
    } catch (error) {
        console.error('\n❌ Test failed with error:', error.message);
        console.error(error.stack);
        process.exit(1);
    }
}

runTest();
