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

import de.accso.flexinale.backoffice.api_contract.event.FilmCreatedEvent;
import de.accso.flexinale.backoffice.api_contract.event.FilmDeletedEvent;
import de.accso.flexinale.backoffice.api_contract.event.FilmUpdatedEvent;
import de.accso.flexinale.besucherportal.application.services.FKKsVTInMemoryCache;
import de.accso.flexinale.common.api.eventbus.EventBus;
import de.accso.flexinale.common.api.eventbus.EventBusFactory;
import de.accso.flexinale.common.api.eventbus.EventNotification;
import de.accso.flexinale.common.api.eventbus.EventSubscriber;
import de.accso.flexinale.common.api.eventbus.EventSubscriber.EventSubscriber3;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static de.accso.flexinale.common.api.eventbus.EventSubscriptionAtStart.START_READING_FROM_BEGINNING;

@SuppressWarnings("unused")
public class FilmSubscriber implements EventSubscriber3<FilmCreatedEvent, FilmUpdatedEvent, FilmDeletedEvent> {
    private static final Logger LOGGER = LoggerFactory.getLogger(FilmSubscriber.class);

    private final FKKsVTInMemoryCache cache;

    private final EventNotification notification;

    @SuppressWarnings({"RedundantCast", "unchecked", "rawtypes"})
    public FilmSubscriber(final EventBusFactory eventBusFactory,
                          final FKKsVTInMemoryCache cache,
                          final EventNotification notification) {
        EventBus<FilmCreatedEvent> createBus = eventBusFactory.createOrGetEventBusFor(FilmCreatedEvent.class);
        EventBus<FilmUpdatedEvent> updateBus = eventBusFactory.createOrGetEventBusFor(FilmUpdatedEvent.class);
        EventBus<FilmDeletedEvent> deleteBus = eventBusFactory.createOrGetEventBusFor(FilmDeletedEvent.class);

        createBus.subscribe(FilmCreatedEvent.class, (EventSubscriber) this, START_READING_FROM_BEGINNING);
        updateBus.subscribe(FilmUpdatedEvent.class, (EventSubscriber) this, START_READING_FROM_BEGINNING);
        deleteBus.subscribe(FilmDeletedEvent.class, (EventSubscriber) this, START_READING_FROM_BEGINNING);

        this.cache = cache;
        this.notification = notification;
    }

    @Override
    public String getName() {
        return FilmSubscriber.class.getName();
    }

    @Override
    public String getGroupName() {
        return "flexinale-distributed-besucherportal"; //TODO make configurable, use "spring.kafka.consumer.group-id" from application.properties
    }

    @Override
    public void receive(final FilmCreatedEvent event) {
        LOGGER.debug("received new event " + event);

        cache.addOrUpdate(event.film);
        this.notification.notify(event);
    }

    @Override
    public void receive2(final FilmUpdatedEvent event) {
        LOGGER.debug("received new event " + event);

        cache.addOrUpdate(event.film);
        this.notification.notify(event);
    }

    @Override
    public void receive3(final FilmDeletedEvent event) {
        LOGGER.debug("received new event " + event);

        cache.delete(event.film);
        this.notification.notify(event);
    }

    public FKKsVTInMemoryCache getCache() {
        return cache;
    }
}
