package be.iminds.ilabt.jfed.experimenter_gui.ext_requests;

import be.iminds.ilabt.jfed.ApplicationParametersModule;
import be.iminds.ilabt.jfed.experimenter_gui.events.OpenRequestRspecFromUrlEvent;
import be.iminds.ilabt.jfed.experimenter_gui.events.OpenTutorialFromUrlEvent;
import be.iminds.ilabt.jfed.experimenter_gui.events.RecoverSliceEvent;
import com.google.common.eventbus.EventBus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.*;

/**
 * This class handles the URI's and file open requests that are received.
 */
@Singleton
public class ExternalUserRequestHandler implements ParameterHandler<Void> {
    private static final Logger LOG = LoggerFactory.getLogger(ExternalUserRequestHandler.class);
    private final EventBus eventBus;
    private final ApplicationParametersModule.ApplicationParameters applicationParameters;

    /**
     * This queue parks all incoming ExternalUserRequests until the main screen is active.
     * When that happens, the activate-function is called.
     */
    private Queue<Object> eventsQueue = new LinkedList<>();

    @Inject
    public ExternalUserRequestHandler(EventBus eventBus,
                                      ApplicationParametersModule.ApplicationParameters applicationParameters) {
        this.eventBus = eventBus;
        this.applicationParameters = applicationParameters;
    }

    public synchronized void activate() {
        LOG.info("Activating ExternalUserRequestHandler: posting {} events", eventsQueue.size());
        eventsQueue.forEach(eventBus::post);
        this.eventsQueue = null;
    }

    public boolean isActive() {
        return eventsQueue == null;
    }


    @Override
    public synchronized Void handleParameters() {
        if (!isActive()) {
            eventsQueue.addAll(processParameters(applicationParameters.getParameters()));
        } else {
            processParameters(applicationParameters.getParameters()).forEach(eventBus::post);
        }

        return null;
    }

    private List<Object> processParameters(Map<String, String> params) {
        List<Object> events = new ArrayList<>();

        if (params.containsKey(StartupParameters.PARAM_RSPEC)) {
            LOG.info("Detected rspec parameter '{}'", params.get(StartupParameters.PARAM_RSPEC));
            events.add(new OpenRequestRspecFromUrlEvent(params.get(StartupParameters.PARAM_RSPEC)));
        }

        if (params.containsKey(StartupParameters.PARAM_SLICE_URN)) {
            LOG.info("Detected slice-urn parameter '{}'", params.get(StartupParameters.PARAM_SLICE_URN));
            events.add(new RecoverSliceEvent(params.get(StartupParameters.PARAM_SLICE_URN)));
        }

        if(params.containsKey(StartupParameters.PARAM_TUTORIAL)){
            LOG.info("Detected tutorial parameter '{}'", params.get(StartupParameters.PARAM_TUTORIAL));
            events.add(new OpenTutorialFromUrlEvent(params.get(StartupParameters.PARAM_TUTORIAL)));
        }

        return events;
    }


}
