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

import be.iminds.ilabt.jfed.experiment.CapabilityChecker;
import be.iminds.ilabt.jfed.experiment.ExperimentController;
import be.iminds.ilabt.jfed.experimenter_gui.TriggeredMessageHandler;
import be.iminds.ilabt.jfed.experimenter_gui.slice.ExperimentViewControllerFactory;
import be.iminds.ilabt.jfed.fedmon.webapi.service.json.Server;
import be.iminds.ilabt.jfed.fedmon.webapi.service.json.TriggeredMessage;
import be.iminds.ilabt.jfed.highlevel.model.SfaModel;
import be.iminds.ilabt.jfed.highlevel.tasks.HighLevelTaskFactory;
import be.iminds.ilabt.jfed.lowlevel.GeniUserProvider;
import be.iminds.ilabt.jfed.lowlevel.api_wrapper.impl.AutomaticAggregateManagerWrapper;
import be.iminds.ilabt.jfed.lowlevel.authority.AuthorityFinder;
import be.iminds.ilabt.jfed.preferences.JFedGuiPreferences;
import be.iminds.ilabt.jfed.rspec.rspec_source.RequestRspecSource;
import be.iminds.ilabt.jfed.ui.javafx.GuiceFXMLUtil;
import be.iminds.ilabt.jfed.util.GeniUrn;
import com.google.common.eventbus.EventBus;
import javafx.application.HostServices;
import javafx.stage.Window;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * User: twalcari
 * Date: 12/2/2014
 * Time: 16:37
 */
@Singleton
public class DialogsFactoryImpl implements DialogsFactory {
    private static final Logger LOG = LoggerFactory.getLogger(DialogsFactoryImpl.class);

    private final GuiceFXMLUtil guiceFXMLUtil;
    private final EventBus eventBus;
    private final GeniUserProvider geniUserProvider;
    private final SfaModel sfaModel;
    private final HighLevelTaskFactory hltf;
    private final ExperimentViewControllerFactory experimentViewControllerFactory;
    private final JFedGuiPreferences jFedPreferences;
    private final AutomaticAggregateManagerWrapper.AutomaticAggregateManagerWrapperFactory
            automaticAggregateManagerWrapperFactory;
    private final AuthorityFinder authorityFinder;
    private final Provider<HostServices> hostServicesProvider;
    private final Provider<CapabilityChecker> capabilityCheckerProvider;
    private final TriggeredMessageHandler triggeredMessageHandler;

    @Inject
    public DialogsFactoryImpl(GuiceFXMLUtil guiceFXMLUtil, EventBus eventBus, GeniUserProvider geniUserProvider, SfaModel sfaModel, HighLevelTaskFactory hltf,
                              ExperimentViewControllerFactory experimentViewControllerFactory,
                              JFedGuiPreferences jFedPreferences,
                              AutomaticAggregateManagerWrapper.AutomaticAggregateManagerWrapperFactory automaticAggregateManagerWrapperFactory,
                              AuthorityFinder authorityFinder, Provider<HostServices> hostServicesProvider,
                              Provider<CapabilityChecker> capabilityCheckerProvider,
                              TriggeredMessageHandler triggeredMessageHandler) {

        this.guiceFXMLUtil = guiceFXMLUtil;
        this.eventBus = eventBus;
        this.geniUserProvider = geniUserProvider;
        this.sfaModel = sfaModel;
        this.hltf = hltf;
        this.experimentViewControllerFactory = experimentViewControllerFactory;
        this.jFedPreferences = jFedPreferences;
        this.automaticAggregateManagerWrapperFactory = automaticAggregateManagerWrapperFactory;
        this.authorityFinder = authorityFinder;
        this.hostServicesProvider = hostServicesProvider;
        this.capabilityCheckerProvider = capabilityCheckerProvider;
        this.triggeredMessageHandler = triggeredMessageHandler;
    }

    @Override
    public void showCreateSliceDialog(Window parentWindow, RequestRspecSource requestRspecSource) {
        try {
            Set<Server> involvedServers = new HashSet<>();
            if (requestRspecSource != null) {
                List<GeniUrn> compManUrns = requestRspecSource.getAllComponentManagerUrns();
                if (compManUrns != null) {
                    for (GeniUrn geniUrn : compManUrns) {
                        Server server = authorityFinder.findByAnyUrn(geniUrn, AuthorityFinder.Purpose.STATUS);
                        if (server != null) {
                            involvedServers.add(server);
                        }
                    }
                }
            }
            triggeredMessageHandler.onEvent(TriggeredMessage.GuiTrigger.RUN_EXPERIMENT, new ArrayList<>(involvedServers));
        } catch (Exception e) {
            LOG.warn("Exception processing TriggeredMessage (will be ignored)", e);
        }

        new StartExperimentDialog(guiceFXMLUtil, parentWindow, requestRspecSource, authorityFinder, geniUserProvider, eventBus).show();
    }

    @Override
    public void showRebootDialog(Window parentWindow, ExperimentController experimentController) {
        new RebootDialog(parentWindow, experimentController, automaticAggregateManagerWrapperFactory).showDialog();
    }

    @Override
    public void showEditSshKeysDialog(Window parentWindow, ExperimentController experimentController) {
        new EditSshKeysDialog(parentWindow, experimentController, geniUserProvider,
                sfaModel, jFedPreferences, capabilityCheckerProvider.get()).showDialog();
    }

    @Override
    public void showShareSliceDialog(Window parentWindow, ExperimentController experimentController) {
        new ShareSliceDialog(parentWindow, experimentController,
                geniUserProvider, sfaModel, hltf).showDialog();

    }

    @Override
    public void showCreateReservationDialog(Window parentWindow, RequestRspecSource requestRspecSource) {
        new CreateReservationDialog(parentWindow, requestRspecSource, hltf, geniUserProvider, sfaModel, eventBus,
                hostServicesProvider, authorityFinder).showDialog();
    }

    @Override
    public void showRenewSliceDialog(Window parentWindow, ExperimentController experimentController) {
        new RenewSliceDialog(parentWindow, experimentController, authorityFinder).showDialog();
    }

    @Override
    public void showTerminateSliceDialog(Window parentWindow, ExperimentController experimentController) {
        new TerminateSliceDialog(parentWindow, experimentController/*, gtsJobFactory, authorityFinder*/).showDialog();
    }

}
