package de.accso.flexinale.common.api.event;

import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;

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

class EventTest {

    @Test
    void testEventConstructor() {
        // arrange
        LocalDateTime now = LocalDateTime.now();

        // act
        EventTestdata.MyNumberEvent event = new EventTestdata.MyNumberEvent(11, 12);

        // assert
        assertThat(event.id).isNotNull();
        assertThat(event.correlationId()).isNotNull();
        assertThat(event.timestamp).isAfterOrEqualTo(now);
        assertThat(event.eventContext().eventHistory.size()).isEqualTo(1);
        assertThat(event.eventContext().eventHistory.getFirst()).isEqualTo(
                new EventContext.EventHistoryElement(event.id, EventTestdata.MyNumberEvent.class));
    }

    @Test
    void testEventConstructorWithHistory() {
        // arrange
        LocalDateTime now = LocalDateTime.now();

        // act
        EventTestdata.MyNumberEvent startEvent =
                new EventTestdata.MyNumberEvent(11, 12);

        EventTestdata.MyMixedEvent  nextEvent  =
                new EventTestdata.MyMixedEvent(startEvent, "13", 14);

        EventTestdata.MyNumberEvent lastEvent =
                new EventTestdata.MyNumberEvent(nextEvent, 15, 16);

        // assert
        assertThat(lastEvent.id).isNotNull();
        assertThat(lastEvent.id).isNotEqualTo( nextEvent.id);
        assertThat(lastEvent.id).isNotEqualTo(startEvent.id);
        assertThat(nextEvent.id).isNotEqualTo(startEvent.id);

        assertThat(lastEvent.correlationId()).isNotNull();
        assertThat(lastEvent.correlationId()).isEqualTo( nextEvent.correlationId());
        assertThat(nextEvent.correlationId()).isEqualTo(startEvent.correlationId());

        assertThat( lastEvent.timestamp).isAfterOrEqualTo( nextEvent.timestamp);
        assertThat( nextEvent.timestamp).isAfterOrEqualTo(startEvent.timestamp);
        assertThat(startEvent.timestamp).isAfterOrEqualTo(now);

        assertThat( lastEvent.eventContext().eventHistory.size()).isEqualTo(3);
        assertThat( nextEvent.eventContext().eventHistory.size()).isEqualTo(2);
        assertThat(startEvent.eventContext().eventHistory.size()).isEqualTo(1);

        assertThat(lastEvent.eventContext().eventHistory.get(0)).isEqualTo(
                new EventContext.EventHistoryElement(startEvent.id, startEvent.getClass()));
        assertThat(lastEvent.eventContext().eventHistory.get(1)).isEqualTo(
                new EventContext.EventHistoryElement(nextEvent.id, nextEvent.getClass()));
        assertThat(lastEvent.eventContext().eventHistory.get(2)).isEqualTo(
                new EventContext.EventHistoryElement(lastEvent.id, lastEvent.getClass()));

        assertThat(nextEvent.eventContext().eventHistory.get(0)).isEqualTo(
                new EventContext.EventHistoryElement(startEvent.id, startEvent.getClass()));
        assertThat(nextEvent.eventContext().eventHistory.get(1)).isEqualTo(
                new EventContext.EventHistoryElement(nextEvent.id, nextEvent.getClass()));

        assertThat(startEvent.eventContext().eventHistory.getFirst()).isEqualTo(
                new EventContext.EventHistoryElement(startEvent.id, startEvent.getClass()));
    }

}

