package com.lingniu.ingest.api.consumer;

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;

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

class EnvelopeConsumerProcessorTest {

    @Test
    void invalidEnvelopePublishesDeadLetterRecordWithKafkaPosition() {
        CapturingDeadLetterSink deadLetters = new CapturingDeadLetterSink();
        EnvelopeConsumerProcessor processor = new EnvelopeConsumerProcessor(
                "event-history", ignored -> EnvelopeIngestResult.invalid("VehicleEnvelope bytes are invalid"), deadLetters);

        EnvelopeIngestResult result = processor.process(
                new EnvelopeConsumerRecord("vehicle.realtime", 2, 42L, "VIN001", new byte[]{0x01, 0x02}));

        assertThat(result.status()).isEqualTo(EnvelopeIngestResult.Status.INVALID_ENVELOPE);
        assertThat(deadLetters.records).singleElement().satisfies(record -> {
            assertThat(record.service()).isEqualTo("event-history");
            assertThat(record.topic()).isEqualTo("vehicle.realtime");
            assertThat(record.partition()).isEqualTo(2);
            assertThat(record.offset()).isEqualTo(42L);
            assertThat(record.key()).isEqualTo("VIN001");
            assertThat(record.status()).isEqualTo(EnvelopeIngestResult.Status.INVALID_ENVELOPE);
            assertThat(record.message()).contains("VehicleEnvelope");
            assertThat(record.payload()).containsExactly(0x01, 0x02);
        });
    }

    @Test
    void processedEnvelopeDoesNotPublishDeadLetter() {
        CapturingDeadLetterSink deadLetters = new CapturingDeadLetterSink();
        EnvelopeConsumerProcessor processor = new EnvelopeConsumerProcessor(
                "vehicle-state", ignored -> EnvelopeIngestResult.processed("event-1", "VIN001"), deadLetters);

        EnvelopeIngestResult result = processor.process(
                new EnvelopeConsumerRecord("vehicle.realtime", 0, 7L, "VIN001", new byte[]{0x0a}));

        assertThat(result.status()).isEqualTo(EnvelopeIngestResult.Status.PROCESSED);
        assertThat(deadLetters.records).isEmpty();
    }

    private static final class CapturingDeadLetterSink implements EnvelopeDeadLetterSink {
        private final List<EnvelopeDeadLetterRecord> records = new ArrayList<>();

        @Override
        public void publish(EnvelopeDeadLetterRecord record) {
            records.add(record);
        }
    }
}
