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

import de.accso.flexinale.FlexinaleDistributedApplicationTestIntegrated;
import de.accso.flexinale.backoffice.api_contract.event.model.FilmTO;
import de.accso.flexinale.backoffice.api_out.event.FilmPublisher;
import de.accso.flexinale.backoffice.domain.model.Film;
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.createFilm;
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 FilmSubscriberTest {

    @Autowired
    FilmSubscriber filmSubscriber;

    @Autowired
    FilmPublisher filmPublisher;

    @Test
    void testPublishAndSubscribeOfFilme() {
        // arrange
        Film film1 = createFilm();
        Film film2 = createFilm();

        Collection<Film> newFilms = List.of(film1, film2);

        // act
        filmPublisher.publishNewFilms(newFilms);
        FilmTO filmTO1 = filmSubscriber.getCache().film(film1.id());
        FilmTO filmTO2 = filmSubscriber.getCache().film(film2.id());

        // assert
        assertThat(filmTO1).isNotNull();
        assertThat(filmTO1.id()).isEqualTo(film1.id());

        assertThat(filmTO2).isNotNull();
        assertThat(filmTO2.id()).isEqualTo(film2.id());

        // act
        List<FilmTO> filme = filmSubscriber.getCache().filme();

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

        // act
        Collection<Film> sameFilmAgain = List.of(film1);
        filmPublisher.publishNewFilms(sameFilmAgain);

        // assert
        assertThat(filmSubscriber.getCache().filme().size()).isEqualTo(2);
    }
}