package be.iminds.ilabt.jfed.experimenter_gui.gts_editor.actions;

import be.iminds.ilabt.jfed.experimenter_gui.gts_editor.EditableGtsDsl;
import be.iminds.ilabt.jfed.experimenter_gui.ui.progressbar.TaskService;
import be.iminds.ilabt.jfed.groovy_dsl.DSLStreamException;
import be.iminds.ilabt.jfed.gts.GtsDslWriter;
import be.iminds.ilabt.jfed.preferences.GuiPreferenceKey;
import be.iminds.ilabt.jfed.preferences.JFedPreferences;
import be.iminds.ilabt.jfed.ui.javafx.dialogs.JFDialogs;
import javafx.concurrent.Task;
import javafx.stage.FileChooser;
import javafx.stage.Window;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileWriter;

/**
 * User: twalcari
 * Date: 5/20/2015
 * Time: 09:14
 */
public class ExportGtsDslAction extends GtsEditorAction<Boolean> {
    private static final Logger LOG = LoggerFactory.getLogger(ExportGtsDslAction.class);

    public static final String GTS_FILE_EXTENSION = ".gts";
    public static final FileChooser.ExtensionFilter GTS_EXTENSION_FILTER =
            new FileChooser.ExtensionFilter("GTS DSL (*" + GTS_FILE_EXTENSION + ")",
                    "*" + GTS_FILE_EXTENSION);

    private final TaskService taskService;
    private final JFedPreferences jFedPreferences;

    ExportGtsDslAction(EditableGtsDsl editableGtsDsl, Window parentWindow,
                       TaskService taskService, JFedPreferences jFedPreferences) {
        super(editableGtsDsl, parentWindow);
        this.taskService = taskService;
        this.jFedPreferences = jFedPreferences;
    }

    @Override
    public Boolean call() {
        try {
            editableGtsDsl.save();
        } catch (DSLStreamException ex) {
            LOG.error("Error while saving DSL: {}", ex.getMessage(), ex);

            JFDialogs.create()
                    .title("Saving GTS DSL failed")
                    .message("An error occured while saving your GTS DSL")
                    .showException(ex);
            return false;
        }


        File file = null;

        while (file == null) {

            FileChooser fc = new FileChooser();
            fc.setTitle("Save GTS DSL");
            fc.getExtensionFilters().add(GTS_EXTENSION_FILTER);
            fc.setInitialFileName(editableGtsDsl.getName() + GTS_FILE_EXTENSION);


            //set the default save dir
            if (System.getProperty("user.home") != null)
                fc.setInitialDirectory(new File(System.getProperty("user.home")));

            if (jFedPreferences.containsPreference(GuiPreferenceKey.PREF_RSPECFOLDER_REQUEST)) {
                File dir = new File(jFedPreferences.getString(GuiPreferenceKey.PREF_RSPECFOLDER_REQUEST));
                if (dir.exists()) {
                    fc.setInitialDirectory(dir);
                }
            }
//
//            if (editableGtsDsl.getFile() != null) {
//                fc.setInitialDirectory(editableGtsDsl.getFile().getParentFile());
//                fc.setInitialFileName(editableGtsDsl.getFile().getName());
//            }

            file = fc.showSaveDialog(parentWindow);

            if (file == null)
                return false;

            //save folder in which the file was saved for future file selector dialogs
            jFedPreferences.setString(GuiPreferenceKey.PREF_RSPECFOLDER_REQUEST,
                    file.getParentFile().getAbsolutePath());

            if (!file.getAbsolutePath().endsWith(GTS_FILE_EXTENSION))
                file = new File(file.getAbsolutePath() + GTS_FILE_EXTENSION);

            String name = file.getName().substring(0, file.getName().length() - GTS_FILE_EXTENSION.length());

            if (!editableGtsDsl.verifyName(name)) {
                JFDialogs.create()
                        .message("The given name is not a valid for GTS. Please choose a name using the following characters: [A-Za-z0-9_]")
                        .showError();
                file = null;

            } else {
                editableGtsDsl.setName(name);
            }
        }


        taskService.submitTask(new ExportGtsDslTask(editableGtsDsl, file));

       // editableGtsDsl.setFile(file);

        return true;
    }


    public class ExportGtsDslTask extends Task<Void> {


        private final EditableGtsDsl editableGtsDsl;
        private final File saveFile;

        public ExportGtsDslTask(EditableGtsDsl editableGtsDsl, File saveFile) {
            this.editableGtsDsl = editableGtsDsl;
            this.saveFile = saveFile;

            updateTitle("Exporting GTS DSL to \"" + saveFile.getAbsolutePath() + "\"");
        }

        @Override
        protected Void call() throws Exception {
            GtsDslWriter gtsDslWriter = new GtsDslWriter(editableGtsDsl.getModel());

            FileWriter writer = new FileWriter(saveFile);
            writer.write(gtsDslWriter.call());
            writer.flush();
            writer.close();

            updateMessage("Successfully exported GTS DSL to \"" + saveFile.getAbsolutePath() + "\"");

            return null;
        }

        @Override
        protected void failed() {
            LOG.error("Error while saving experiment to file '" + saveFile.getAbsolutePath() + "'", getException());

            JFDialogs.create()
                    .owner(parentWindow)
                    .message("An error occurred while exporting the GTS DSL.")
                    .masthead("Error")
                    .title("Error")
                    .showException(getException());

        }


    }


}
