package de.accso.flexinale.besucherportal.api_in.event;

import de.accso.flexinale.FlexinaleDistributedApplicationTestIntegrated;
import de.accso.flexinale.backoffice.api_contract.event.model.KinoTO;
import de.accso.flexinale.backoffice.api_out.event.KinoPublisher;
import de.accso.flexinale.backoffice.domain.model.Kino;
import de.accso.flexinale.common.shared_kernel.DoNotCheckInArchitectureTests;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.Collection;
import java.util.List;

import static de.accso.flexinale.shared_code_for_test.TestDataBuilder.createKinoWithKinosaele;
import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = {FlexinaleDistributedApplicationTestIntegrated.class})
@ActiveProfiles("test-integrated")
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
@ExtendWith(SpringExtension.class)
@DoNotCheckInArchitectureTests
public class KinoSubscriberTest {

    @Autowired
    KinoSubscriber kinoSubscriber;

    @Autowired
    KinoPublisher kinoPublisher;

    @Test
    void testPublishAndSubscribeOfKinos() {
        // arrange
        Kino kino1 = createKinoWithKinosaele();
        Kino kino2 = createKinoWithKinosaele();

        Collection<Kino> newKinos = List.of(kino1, kino2);

        kinoPublisher.publishNewKinos(newKinos);

        // act
        KinoTO kinoTO1 = kinoSubscriber.getCache().kino(kino1.id());
        KinoTO kinoTO2 = kinoSubscriber.getCache().kino(kino2.id());

        // assert
        assertThat(kinoTO1).isNotNull();
        assertThat(kinoTO1.id()).isEqualTo(kino1.id());
        assertThat(kinoTO1.kinoSaele().size()).isEqualTo(kino1.kinoSaele.size());

        assertThat(kinoTO2).isNotNull();
        assertThat(kinoTO2.id()).isEqualTo(kino2.id());
        assertThat(kinoTO2.kinoSaele().size()).isEqualTo(kino2.kinoSaele.size());

        // act
        List<KinoTO> kinos = kinoSubscriber.getCache().kinos();

        // assert
        assertThat(kinos.size()).isEqualTo(2);

        // act
        Collection<Kino> sameKinoAgain = List.of(kino1);
        kinoPublisher.publishNewKinos(sameKinoAgain);

        // assert
        assertThat(kinoSubscriber.getCache().kinos().size()).isEqualTo(2);
    }
}
