package eu.teraflow.automation;

import eu.teraflow.automation.context.ContextService;
import eu.teraflow.automation.device.model.DeviceEvent;
import io.quarkus.runtime.StartupEvent;
import io.smallrye.mutiny.Multi;
import java.time.Duration;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import org.jboss.logging.Logger;

@ApplicationScoped
public class ContextSubscriber {

    private static final Logger LOGGER = Logger.getLogger(ContextSubscriber.class);

    private final ContextService contextService;
    private final AutomationService automationService;
    private final AutomationConfiguration automationConfiguration;

    @Inject
    public ContextSubscriber(
            ContextService contextService,
            AutomationService automationService,
            AutomationConfiguration automationConfiguration) {
        this.contextService = contextService;
        this.automationService = automationService;
        this.automationConfiguration = automationConfiguration;
    }

    public void listenForDeviceEvents() {

        Multi<DeviceEvent> deviceEventsMulti =
                contextService
                        .getDeviceEvents()
                        .onFailure()
                        .retry()
                        .withBackOff(Duration.ofSeconds(1))
                        .withJitter(0.2)
                        .atMost(10);

        deviceEventsMulti
                .onItem()
                .transformToUniAndConcatenate(
                        deviceEvent -> automationService.addDevice(deviceEvent.getDeviceId()));
    }

    void onStart(@Observes StartupEvent ev) {

        if (automationConfiguration.shouldSubscribeToContextComponent()) {
            LOGGER.info("Listening for Device events...");
            listenForDeviceEvents();
        } else {
            LOGGER.info("Not listening for Device events...");
        }
    }
}
