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

import be.iminds.ilabt.jfed.util.OSDetector;
import javafx.fxml.FXMLLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.inject.Provider;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

/**
 * SubSectionLibrary
 * <p/>
 * This class allows acces sto the preferences sub section.
 * It allows some filters to be used
 */
public class SubSectionLibrary {
    private static final Logger LOG = LoggerFactory.getLogger(SubSectionLibrary.class);
    private OSDetector.OS os;

    private static final String GENERAL_PANE_FXML = "subsections/GeneralPane.fxml";
    private static final String TERMINAL_COMMAND_PANE_FXML = "subsections/TerminalCommandPane.fxml";
    private static final String SSH_COMMAND_PANE_FXML = "subsections/SshCommandPane.fxml";
    private static final String UNIX_SSH_AUTHENTICATION_PANE_FXML = "subsections/UnixSshAuthenticationPane.fxml";

    private static final String PUTTY_PANE_FXML = "subsections/PuttyPane.fxml";
    private static final String WINDOWS_SSH_AUTHENTICATION_PANE_FXML = "subsections/WindowsSshAuthenticationPane.fxml";

    private static final String PROXY_PANE_FXML = "subsections/ProxyPane.fxml";
    private static final String SCS_PANE_FXML = "subsections/ScsPane.fxml";
    private static final String LOGININFO_PANE_FXML = "subsections/LoginInfoPane.fxml";
    private static final String LOGIN_PANE_FXML = "subsections/LoginPane.fxml";
    private static final String TESTBEDS_PANE = "subsections/TestbedsPane.fxml";
    private static final String EDITOR_PANE = "subsections/EditorPane.fxml";
    private static final String GTS_PANE = "subsections/GtsPane.fxml";
    private static final String LOGLEVEL_PANE = "subsections/LogLevelPane.fxml";

    private final Provider<FXMLLoader> loaderProvider;

    @Inject
    SubSectionLibrary(Provider<FXMLLoader> loaderProvider) {
        this.loaderProvider = loaderProvider;


    }


    public SubSectionLibrary filterByOs(OSDetector.OS os) {
        this.os = os;
        return this;
    }

    public List<PreferencesSubPane> get() {
        List<PreferencesSubPane> res = new ArrayList<>();
        res.add(initializePane(GENERAL_PANE_FXML));

        if (os != null && OSDetector.getUnixLikeOsFilter().includedOs(os)) {
            res.add(initializePane(TERMINAL_COMMAND_PANE_FXML));
            res.add(initializePane(SSH_COMMAND_PANE_FXML));
            res.add(initializePane(UNIX_SSH_AUTHENTICATION_PANE_FXML));
        }
        if (os != null && os == OSDetector.OS.WIN) {
            res.add(initializePane(PUTTY_PANE_FXML));
            res.add(initializePane(WINDOWS_SSH_AUTHENTICATION_PANE_FXML));
        }
        res.add(initializePane(PROXY_PANE_FXML));
        res.add(initializePane(SCS_PANE_FXML));
        res.add(initializePane(LOGININFO_PANE_FXML));
        res.add(initializePane(LOGIN_PANE_FXML));
        res.add(initializePane(TESTBEDS_PANE));
        res.add(initializePane(EDITOR_PANE));
        res.add(initializePane(GTS_PANE));
        res.add(initializePane(LOGLEVEL_PANE));

        //remove any null added because a panel failed to load
        for (ListIterator<PreferencesSubPane> it = res.listIterator(); it.hasNext();) {
            PreferencesSubPane psp = it.next();
            if (psp == null) {
                LOG.error("A Preference sub panel failed to load!");
                assert false;
                it.remove();
            }
        }

        return res;
    }

    private PreferencesSubPane initializePane(String fxml) {
        FXMLLoader loader = loaderProvider.get();
        try {
            loader.setLocation(getClass().getResource(fxml));

            loader.load();
            PreferencesSubPane result = loader.getController();

            assert result != null;

            if (result == null) {
                LOG.error("Failed to load panel \""+fxml+"\"");
                return null;
            }

            return result;
        } catch (IOException e) {
            LOG.error("Could not initialize preferences pane \"" + fxml+"\"", e);
            assert false;
            return null;
        }

    }
}
