package be.iminds.ilabt.jfed.experimenter_gui.editor.rspec_validation;

import be.iminds.ilabt.jfed.rspec.model.ModelRspecType;
import be.iminds.ilabt.jfed.rspec.model.javafx_impl.FXModelRspec;
import be.iminds.ilabt.jfed.rspec.rspec_source.RequestRspecSource;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType;
import javafx.stage.Window;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Optional;

/**
 * User: twalcari
 * Date: 1/22/2015
 * Time: 17:01
 */
public class ExperimentCommandNamespaceValidator implements RspecValidator {
    private static final Logger LOG = LoggerFactory.getLogger(ExperimentCommandNamespaceValidator.class);

    @Override
    public RspecValidationResult validateRSpec(RspecCheckReason reason, RequestRspecSource requestRspecSource, Window dialogOwner) {
        if (requestRspecSource.getRspecXmlString().contains("experimentCommand xmlns=\"http://jfed.iminds.be/rspec/ext/jfed/1\"")) {
            String abortText = "Abort";
            String fixText = "Fix and continue";
            String ignoreText = "Keep as is and continue";
            boolean showIgnore = false;
            switch (reason) {
                case SWITCH_TO_VISUAL_EDITOR: {
                    abortText = "Keep as is but return to editor";
                    ignoreText = "Ignore";
                    showIgnore = true;
                    break;
                }
                case RUN_EXPERIMENT: {
                    abortText = "Abort and continue editing";
                    ignoreText = "Ignore and Run Experiment Anyway";
                    fixText = "Fix and Run Experiment";
                    showIgnore = true;
                    break;
                }
                case CHECK_RSPEC: {
                    abortText = "Keep as is";
                    fixText = "Fix";
                    showIgnore = false;
                    break;
                }
                case OPENED_FILE: {
                    abortText = "Keep as is";
                    fixText = "Fix";
                    showIgnore = false;
                    break;
                }
            }

            ButtonType fixButtonType = new ButtonType(fixText, ButtonBar.ButtonData.YES);
            ButtonType ignoreButtonType = new ButtonType(ignoreText, ButtonBar.ButtonData.CANCEL_CLOSE);
            ButtonType abortButtonType = new ButtonType(abortText, ButtonBar.ButtonData.CANCEL_CLOSE);

            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setTitle("Wrong experimentCommands namespace");
            alert.setContentText("Problem in RSpec:\n" +
                    "Some experimentCommands in the RSpec are from an older jFed version that had a bug causing them to be in the wrong namespace.\n\n" +
                    "Do you want to fix this by automatically changing to the correct namespace?");

            if (showIgnore)
                alert.getButtonTypes().setAll(fixButtonType, ignoreButtonType, abortButtonType);
            else
                alert.getButtonTypes().setAll(fixButtonType, abortButtonType);
            Optional<ButtonType> result = alert.showAndWait();

            if (result.isPresent() && result.get() == fixButtonType) {

                LOG.info("Fixing experimentCommands namespace");
                //automatically fixed when going to FXModelRspec and back.
                final FXModelRspec modelRspec = requestRspecSource.getModelRspec(ModelRspecType.FX);
                return new RspecValidationResult(modelRspec);
            } else if (result.isPresent() && result.get() == ignoreButtonType) {
                return new RspecValidationResult(requestRspecSource, false /* == ignore */);
            } else {
                assert !result.isPresent() || result.get() == abortButtonType;
                return new RspecValidationResult(requestRspecSource, true/* == abort*/);
            }
        }

        return null;
    }
}
