package com.lingniu.ingest.sink.kafka;

import com.lingniu.ingest.api.consumer.EnvelopeConsumerProcessor;
import com.lingniu.ingest.api.consumer.EnvelopeIngestResult;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.consumer.OffsetResetStrategy;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

@ExtendWith(OutputCaptureExtension.class)
class KafkaSinkConsumerAutoConfigurationTest {

    private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
            .withUserConfiguration(KafkaSinkAutoConfiguration.class, KafkaSinkConsumerAutoConfiguration.class)
            .withAllowBeanDefinitionOverriding(true)
            .withBean("vehicleStateEnvelopeConsumerProcessor", EnvelopeConsumerProcessor.class,
                    () -> new EnvelopeConsumerProcessor(
                            "vehicle-state",
                            bytes -> EnvelopeIngestResult.processed("evt-1", "VIN001"),
                            record -> {}))
            .withBean("kafkaProducer", KafkaProducer.class, KafkaSinkConsumerAutoConfigurationTest::kafkaProducer)
            .withBean(KafkaEnvelopeConsumerFactory.class,
                    () -> new KafkaEnvelopeConsumerFactory(props -> new MockConsumer<>(OffsetResetStrategy.EARLIEST)))
            .withPropertyValues(
                    "lingniu.ingest.sink.kafka.enabled=true",
                    "lingniu.ingest.sink.kafka.consumer.enabled=true",
                    "lingniu.ingest.sink.kafka.consumer.auto-startup=false",
                    "lingniu.ingest.sink.kafka.consumer.bindings.vehicleStateEnvelopeConsumerProcessor.group-id=vehicle-state",
                    "lingniu.ingest.sink.kafka.consumer.bindings.vehicleStateEnvelopeConsumerProcessor.topics[0]=vehicle.realtime");

    @Test
    void createsKafkaEnvelopeConsumerRunnerWhenConsumerBindingIsConfigured(CapturedOutput output) {
        contextRunner.run(context -> {
            assertThat(context).hasSingleBean(KafkaEnvelopeConsumerRunner.class);
            assertThat(context.getBean(KafkaEnvelopeConsumerRunner.class).workers()).hasSize(1);
        });
        assertThat(output).doesNotContain("114.55.58.251");
    }

    @SuppressWarnings("unchecked")
    private static KafkaProducer<String, byte[]> kafkaProducer() {
        return mock(KafkaProducer.class);
    }
}
