package cz.moneta.test.system.messaging.kafka;

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.harness.annotations.TestCase;
import cz.moneta.test.harness.annotations.TestScenario;
import org.junit.jupiter.api.Assertions;

import java.util.concurrent.TimeUnit;


@TestScenario(name = "Test Kafka consume functions")
public class KafkaConsumerTest {

    @TestCase(name = "Filtering by key")
    public void filteringByKey(Harness harness) {
        harness.withKafka()
                .fromTopic("TP_CVM_CARD-AUTHORIZATION-NOTIFICATION_STREAM_APP")
                .startFromBeginning()
                .receiveWhere(msg -> msg.getKey().equals("happyday_VZI23"))
                .withTimeout(10, TimeUnit.SECONDS);
    }

    @TestCase(name = "Receive message with filter")
    public void receiveMessageWithFilter(Harness harness) {
        harness.withKafka()
                .fromTopic("order-events")
                .receiveWhere(msg -> msg.extract("orderId").equals("123"))
                .withTimeout(30, TimeUnit.SECONDS)
                .andAssertFieldValue("status", "CREATED");
    }

    @TestCase(name = "Filtering by array value")
    public void filteringByArrayValue(Harness harness) {
        harness.withKafka()
                .fromTopic("order-events")
                .receiveWhere(msg -> msg.extract("orderId").equals("123"))
                .withTimeout(30, TimeUnit.SECONDS);
    }

    @TestCase(name = "Filtering by more values 'AND'")
    public void filteringByMoreVlaues(Harness harness) {
        harness.withKafka()
                .fromTopic("order-events")
                .receiveWhere(msg ->
                        msg.extract("orderId").equals("123")
                                && msg.extract("status").equals("CREATED"))
                .withTimeout(30, TimeUnit.SECONDS);
    }

    @TestCase(name = "Filtering by headers")
    public void filteringByHeaders(Harness harness) {
        harness.withKafka()
                .fromTopic("order-events")
                .receiveWhere(msg -> "req-001".equals(msg.getHeader("requestID")))
                .withTimeout(30, TimeUnit.SECONDS);
    }

    @TestCase(name = "Filtering by key")
    public void filteringBykey(Harness harness) {
        harness.withKafka()
                .fromTopic("order-events")
                .receiveWhere(msg -> "order-123".equals(msg.getKey()))
                .withTimeout(30, TimeUnit.SECONDS);
    }

    @TestCase(name = "Filtering by header and attribute")
    public void filteringByHeaderAndAttribute(Harness harness) {
        harness.withKafka()
                .fromTopic("order-events")
                .receiveWhere(msg ->
                        "act-555".equals(msg.getHeader("activityID"))
                                && msg.extract("status").equals("CREATED"))
                .withTimeout(30, TimeUnit.SECONDS);
    }

    @TestCase(name = "First Message")
    public void getFirstMessage(Harness harness) {
        harness.withKafka()
                .fromTopic("order-events")
                .receiveWhere(msg -> true)
                .withTimeout(10, TimeUnit.SECONDS);
    }

    @TestCase(name = "Receive message with timeout")
    public void receiveMEssageWithTimeout(Harness harness) {
        harness.withKafka()
                .fromTopic("order-events")
                .receiveWhere(msg -> msg.extract("orderId").equals("123"))
                .withTimeout(60, TimeUnit.SECONDS);
    }


    @TestCase(name = "Assert methods test")
    public void assertMethods(Harness harness) {
        String text = harness.withKafka()
                .fromTopic("order-events")
                .receiveWhere(msg -> msg.extract("orderId").equals("555"))
                .withTimeout(30, TimeUnit.SECONDS)
                // Assert na hodnotu pole (dot/bracket notace)
                .andAssertFieldValue("status", "CREATED")
                .andAssertFieldValue("items[0].sku", "A001")
                // Assert na přítomnost/nepřítomnost pole
                .andAssertPresent("items[0].qty")
                .andAssertNotPresent("deletedField")
                // Assert na Kafka header
                .andAssertHeaderValue("requestID", "req-001")
                // Extrakce hodnoty pro další použití v testu
                .extract("items[1].note").asText();
        Assertions.assertEquals("fragile", text);
    }

}
