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

import be.iminds.ilabt.jfed.experiment.SshConnectionPoolFactory;
import be.iminds.ilabt.jfed.experimenter_gui.dialogs.DialogsFactory;
import be.iminds.ilabt.jfed.experimenter_gui.slice.actions.ExperimentActionsFactory;
import be.iminds.ilabt.jfed.experimenter_gui.slice.events.*;
import be.iminds.ilabt.jfed.experimenter_gui.slice.scp.SCPDownloadTask;
import be.iminds.ilabt.jfed.experimenter_gui.slice.scp.SCPUploadTask;
import be.iminds.ilabt.jfed.experimenter_gui.util.DateTimeUtils;
import be.iminds.ilabt.jfed.highlevel.model.Slice;
import be.iminds.ilabt.jfed.ui.javafx.dialogs.JFDialogs;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;

import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;

/**
 * User: twalcari
 * Date: 5/12/2015
 * Time: 15:38
 */
@Singleton
public class ExperimentEventHandler {
    @SuppressWarnings("unused")
    private final EventBus eventBus;
    private final DialogsFactory dialogsFactory;
    private final ExperimentActionsFactory experimentActionsFactory;
    private final Provider<SshConnectionPoolFactory> sshConnectionPoolFactoryProvider;

    @Inject
    public ExperimentEventHandler(EventBus eventBus, DialogsFactory dialogsFactory,
                                  ExperimentActionsFactory experimentActionsFactory,
                                  Provider<SshConnectionPoolFactory> sshConnectionPoolFactoryProvider) {
        this.eventBus = eventBus;
        this.dialogsFactory = dialogsFactory;
        this.experimentActionsFactory = experimentActionsFactory;
        this.sshConnectionPoolFactoryProvider = sshConnectionPoolFactoryProvider;
    }

    @Subscribe
    public void handleUpdateExperimentEvent(UpdateExperimentEvent updateExperimentEvent) {
        updateExperimentEvent.getExperimentController().requestUpdate();
    }

    @Subscribe
    public void handleTerminateExperimentEvent(TerminateExperimentEvent event) {
        dialogsFactory.showTerminateSliceDialog(event.getParentWindow(), event.getExperimentController());
    }

    @Subscribe
    public void handleRenewExperimentEvent(RenewExperimentEvent event) {
        Slice slice = event.getExperimentController().getExperiment().getSlice();

        assert slice.getExpirationDate() != null;
        Instant sliceExpirationTime = slice.getExpirationDate();

        if (sliceExpirationTime.isBefore(Instant.now())) {
            JFDialogs.create()
                    .owner(event.getParentWindow())
                    .message(String.format("The experiment %s has expired on %s. It can therefore not be renewed again.",
                            slice.getName(),
                            DateTimeUtils.DATE_HOUR_MINUTES_FORMATTER.format(LocalDateTime.ofInstant(sliceExpirationTime, ZoneId.systemDefault()))))
                    .masthead("Experiment has expired")
                    .title("Experiment has expired").showError();
        } else {
            dialogsFactory.showRenewSliceDialog(event.getParentWindow(), event.getExperimentController());
        }
    }

    @Subscribe
    public void handleRebootExperimentEvent(RebootExperimentEvent event) {
        dialogsFactory.showRebootDialog(event.getParentWindow(),
                event.getExperimentController());
    }

    @Subscribe
    public void handleEditSshKeysEvent(EditSshKeysEvent event) {
        dialogsFactory.showEditSshKeysDialog(event.getParentWindow(),
                event.getExperimentController());
    }

    @Subscribe
    public void handleShareExperimentEvent(ShareExperimentEvent event) {
        dialogsFactory.showShareSliceDialog(event.getParentWindow(),
                event.getExperimentController());
    }

    @Subscribe
    public void handleSaveExperimentEvent(SaveExperimentEvent event) {
        experimentActionsFactory.createSaveManifestAction(event.getExperimentViewController(), event.isSaveToCsv()).run();
    }

    @Subscribe
    public void handleExportToolsConfigFilesEvent(ExportToolsConfigFilesEvent event) {
        experimentActionsFactory.createExportToolsConfigFilesAction(event.getParentWindow(), event.getExperimentViewController()).run();
    }

    @Subscribe
    public void handleScpEvent(SCPEvent event) {
        if(event.isUpload()) {
            eventBus.post(new SCPUploadTask(event.getExperiment(), event.getNode(), event.getFrom(), event.getTo(), sshConnectionPoolFactoryProvider.get()));
        }            else{

            eventBus.post(new SCPDownloadTask(event.getExperiment(), event.getNode(), event.getFrom(), event.getTo(), sshConnectionPoolFactoryProvider.get()));
        }
    }

}
