{%- import "cloudevents.jinja.include" as cloudEvents %}
{%- import "util.jinja.include" as util -%}
{%- set messagegroups = root.messagegroups %}
{%- set uses_ce_message = (root | exists("envelope","CloudEvents/1.0")) %}
{%- set data_module_name = data_project_name | strip_invalid_identifier_characters %}
// This code was generated by the xRegistry tool.
// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.

import { Kafka, Partitioners } from 'kafkajs';
import { KafkaContainer, StartedKafkaContainer } from '@testcontainers/kafka';
{%- if uses_ce_message %}
import { CloudEvent } from 'cloudevents';
{%- endif %}
import * as {{ data_module_name }} from '../../{{ data_project_name }}/dist/index.js';
{% for messagegroupid, messagegroup in messagegroups.items() -%}
{%- set pascal_group_name = messagegroupid | pascal %}
{%- set class_name = ( pascal_group_name | strip_namespace ) + "Producer" %}
import { {{ class_name }} } from '../src/producer';
{%- endfor %}

describe('{{ project_name }} Kafka Producer Tests', () => {
    let kafkaContainer: StartedKafkaContainer;
    let kafka: Kafka;
    let bootstrapServers: string;
    const topicName = 'testtopic';
    
    beforeAll(async () => {
        // Start Kafka container using official testcontainers module
        // The KafkaContainer exposes port 9093 for client connections
        kafkaContainer = await new KafkaContainer('confluentinc/cp-kafka:7.5.0')
            .withKraft()  // Use KRaft mode (recommended)
            .start();
        
        const host = kafkaContainer.getHost();
        const port = kafkaContainer.getMappedPort(9093);
        bootstrapServers = `${host}:${port}`;
        
        // Give Kafka time to fully initialize
        await new Promise(resolve => setTimeout(resolve, 10000));
        
        kafka = new Kafka({
            clientId: 'test-client',
            brokers: [bootstrapServers],
            retry: {
                initialRetryTime: 100,
                retries: 8
            }
        });
        
        // Create single shared topic for all tests (matches C# pattern)
        const admin = kafka.admin();
        await admin.connect();
        await admin.createTopics({
            topics: [{
                topic: topicName,
                numPartitions: 1,
                replicationFactor: 1
            }]
        });
        await admin.disconnect();
    }, 60000);
    
    afterAll(async () => {
        if (kafkaContainer) {
            await kafkaContainer.stop();
        }
    });
    
    {% for messagegroupid, messagegroup in messagegroups.items() -%}
    {%- set uses_cloudevents_message = (messagegroup | exists("envelope","CloudEvents/1.0")) %}
    {%- set pascal_group_name = messagegroupid | pascal %}
    {%- set class_name = ( pascal_group_name | strip_namespace ) + "Producer" %}
    
    describe('{{ pascal_group_name }} Message Group', () => {
        {% for messageid, message in messagegroup.messages.items() -%}
        {%- set messagename = messageid | strip_namespace | pascal -%}
        {%- set message_body_type = util.body_type(data_project_name, root, message) -%}
        {%- set has_schema = message.dataschemauri or message.dataschema -%}
        
        test('should send {{ messagename }} event', async () => {
            // Matches C# test pattern: just send the message, verify no exception thrown
            const kafkaProducer = kafka.producer({
                createPartitioner: Partitioners.LegacyPartitioner
            });
            await kafkaProducer.connect();
            
            try {
                const producer = new {{ class_name }}(kafkaProducer, topicName);
                {%- if has_schema %}
                const testData = {{ message_body_type }}.createInstance();
                {%- else %}
                const testData = {} as {{ message_body_type }};
                {%- endif %}
                
                // Send 5 messages to test proper message handling
                for (let i = 0; i < 5; i++) {
                    await producer.send{{ messagename }}(testData);
                }
                
                // Test passes if all sends succeed without throwing
                expect(true).toBe(true);
            } finally {
                await kafkaProducer.disconnect();
            }
        }, 10000);
        {% endfor %}
    });
    {% endfor %}
});
