#!/usr/bin/env node
// Test script for Dictionary transport testing
// Tests sending 1 large and 1 small Dictionaries via direct and link transport
// Uses NATSBridge.js smartsend with "dictionary" type

const { smartsend, uuid4, log_trace } = require('./src/NATSBridge');

// Configuration
const SUBJECT = "/NATSBridge_dict_test";
const NATS_URL = "nats.yiem.cc";
const FILESERVER_URL = "http://192.168.88.104:8080";

// Create correlation ID for tracing
const correlation_id = uuid4();

// Helper: Log with correlation ID
function log_trace(message) {
    const timestamp = new Date().toISOString();
    console.log(`[${timestamp}] [Correlation: ${correlation_id}] ${message}`);
}

// File upload handler for plik server
async function plik_upload_handler(fileserver_url, dataname, data, correlation_id) {
    // Get upload ID
    const url_getUploadID = `${fileserver_url}/upload`;
    const headers = {
        "Content-Type": "application/json"
    };
    const body = JSON.stringify({ OneShot: true });
    
    let response = await fetch(url_getUploadID, {
        method: "POST",
        headers: headers,
        body: body
    });
    
    if (!response.ok) {
        throw new Error(`Failed to get upload ID: ${response.status} ${response.statusText}`);
    }
    
    const responseJson = await response.json();
    const uploadid = responseJson.id;
    const uploadtoken = responseJson.uploadToken;
    
    // Upload file
    const formData = new FormData();
    const blob = new Blob([data], { type: "application/octet-stream" });
    formData.append("file", blob, dataname);
    
    response = await fetch(`${fileserver_url}/file/${uploadid}`, {
        method: "POST",
        headers: {
            "X-UploadToken": uploadtoken
        },
        body: formData
    });
    
    if (!response.ok) {
        throw new Error(`Failed to upload file: ${response.status} ${response.statusText}`);
    }
    
    const fileResponseJson = await response.json();
    const fileid = fileResponseJson.id;
    
    const url = `${fileserver_url}/file/${uploadid}/${fileid}/${encodeURIComponent(dataname)}`;
    
    return {
        status: response.status,
        uploadid: uploadid,
        fileid: fileid,
        url: url
    };
}

// Sender: Send Dictionaries via smartsend
async function test_dict_send() {
    // Create a small Dictionary (will use direct transport)
    const small_dict = {
        name: "Alice",
        age: 30,
        scores: [95, 88, 92],
        metadata: {
            height: 155,
            weight: 55
        }
    };
    
    // Create a large Dictionary (will use link transport if > 1MB)
    const large_dict_ids = [];
    const large_dict_names = [];
    const large_dict_scores = [];
    const large_dict_categories = [];
    
    for (let i = 0; i < 50000; i++) {
        large_dict_ids.push(i + 1);
        large_dict_names.push(`User_${i}`);
        large_dict_scores.push(Math.floor(Math.random() * 100) + 1);
        large_dict_categories.push(`Category_${Math.floor(Math.random() * 10) + 1}`);
    }
    
    const large_dict = {
        ids: large_dict_ids,
        names: large_dict_names,
        scores: large_dict_scores,
        categories: large_dict_categories,
        metadata: {
            source: "test_generator",
            timestamp: new Date().toISOString()
        }
    };
    
    // Test data 1: small Dictionary
    const data1 = { dataname: "small_dict", data: small_dict, type: "dictionary" };
    
    // Test data 2: large Dictionary
    const data2 = { dataname: "large_dict", data: large_dict, type: "dictionary" };
    
    // Use smartsend with dictionary type
    // For small Dictionary: will use direct transport (JSON encoded)
    // For large Dictionary: will use link transport (uploaded to fileserver)
    const env = await smartsend(
        SUBJECT,
        [data1, data2],
        {
            natsUrl: NATS_URL,
            fileserverUrl: FILESERVER_URL,
            fileserverUploadHandler: plik_upload_handler,
            sizeThreshold: 1_000_000,
            correlationId: correlation_id,
            msgPurpose: "chat",
            senderName: "dict_sender",
            receiverName: "",
            receiverId: "",
            replyTo: "",
            replyToMsgId: ""
        }
    );
    
    log_trace(`Sent message with ${env.payloads.length} payloads`);
    
    // Log transport type for each payload
    for (let i = 0; i < env.payloads.length; i++) {
        const payload = env.payloads[i];
        log_trace(`Payload ${i + 1} ('${payload.dataname}'):`);
        log_trace(`  Transport: ${payload.transport}`);
        log_trace(`  Type: ${payload.type}`);
        log_trace(`  Size: ${payload.size} bytes`);
        log_trace(`  Encoding: ${payload.encoding}`);
        
        if (payload.transport === "link") {
            log_trace(`  URL: ${payload.data}`);
        }
    }
}

// Run the test
console.log("Starting Dictionary transport test...");
console.log(`Correlation ID: ${correlation_id}`);

// Run sender
console.log("start smartsend for dictionaries");
test_dict_send();

console.log("Test completed.");