package com.lingniu.ingest.sink.kafka;

import com.lingniu.ingest.api.consumer.EnvelopeDeadLetterRecord;
import com.lingniu.ingest.api.consumer.EnvelopeIngestResult;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.ByteArraySerializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.junit.jupiter.api.Test;

import java.nio.charset.StandardCharsets;
import java.time.Instant;

import static org.assertj.core.api.Assertions.assertThat;

class KafkaEnvelopeDeadLetterSinkTest {

    @Test
    void publishesDeadLetterRecordToConfiguredDlqTopicWithDiagnosticHeaders() {
        MockProducer<String, byte[]> producer = new MockProducer<>(
                true, new StringSerializer(), new ByteArraySerializer());
        KafkaEnvelopeDeadLetterSink sink = new KafkaEnvelopeDeadLetterSink(producer, "vehicle.consumer.dlq");
        EnvelopeDeadLetterRecord record = new EnvelopeDeadLetterRecord(
                "event-history",
                "vehicle.realtime",
                3,
                99L,
                "VIN001",
                EnvelopeIngestResult.Status.INVALID_ENVELOPE,
                "",
                "",
                "VehicleEnvelope bytes are invalid",
                new byte[]{0x01, 0x02},
                Instant.parse("2026-06-22T08:00:00Z"));

        sink.publish(record);

        assertThat(producer.history()).hasSize(1);
        ProducerRecord<String, byte[]> sent = producer.history().getFirst();
        assertThat(sent.topic()).isEqualTo("vehicle.consumer.dlq");
        assertThat(sent.key()).isEqualTo("VIN001");
        assertThat(sent.value()).containsExactly(0x01, 0x02);
        assertThat(header(sent, "dlq-service")).isEqualTo("event-history");
        assertThat(header(sent, "dlq-source-topic")).isEqualTo("vehicle.realtime");
        assertThat(header(sent, "dlq-source-partition")).isEqualTo("3");
        assertThat(header(sent, "dlq-source-offset")).isEqualTo("99");
        assertThat(header(sent, "dlq-status")).isEqualTo("INVALID_ENVELOPE");
        assertThat(header(sent, "dlq-message")).isEqualTo("VehicleEnvelope bytes are invalid");
    }

    private static String header(ProducerRecord<String, byte[]> record, String key) {
        return new String(record.headers().lastHeader(key).value(), StandardCharsets.UTF_8);
    }
}
