package be.iminds.ilabt.jfed.ui.javafx.automated_testing_gui;

import be.iminds.ilabt.jfed.BaseGuiModule;
import be.iminds.ilabt.jfed.UncaughtGuiExceptionLogger;
import be.iminds.ilabt.jfed.highlevel.HighLevelModule;
import be.iminds.ilabt.jfed.highlevel.LowLevelModule;
import be.iminds.ilabt.jfed.highlevel.SfaOnlyExperimentModule;
import be.iminds.ilabt.jfed.highlevel.UserLoginModelModule;
import be.iminds.ilabt.jfed.highlevel.controller.TaskThread;
import be.iminds.ilabt.jfed.lowlevel.GeniUser;
import be.iminds.ilabt.jfed.lowlevel.GeniUserProvider;
import be.iminds.ilabt.jfed.ssh_terminal_tool.unix.SshAgentHelper;
import be.iminds.ilabt.jfed.ui.javafx.userlogin.AdvancedUserLoginDialog;
import be.iminds.ilabt.jfed.util.GuiceContext;
import com.google.inject.Module;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
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;

public class AutomatedTesterStandalone extends Application implements GeniUserProvider{
    private static final Logger LOG = LoggerFactory.getLogger(AutomatedTesterStandalone.class);
    private static final String AUTOMATED_TESTER_FXML = "AutomatedTester.fxml";
    /**
     * The main() method is ignored in correctly deployed JavaFX application.
     * main() serves only as fallback in case the application can not be
     * launched through deployment artifacts, e.g., in IDEs with limited FX
     * support. NetBeans ignores main().
     *
     * @param args the command line arguments
     */
    public static boolean debugEnabled = false;
    private final GuiceContext context = new GuiceContext(this, () -> {
        List<Module> modules = new ArrayList<>();
        modules.add(new LowLevelModule());
        modules.add(new HighLevelModule());
        modules.add(new SfaOnlyExperimentModule());
        modules.add(new UserLoginModelModule(true));
        modules.add(new BaseGuiModule());
        modules.add(binder -> binder.bind(GeniUserProvider.class).toInstance(AutomatedTesterStandalone.this));
        return modules;
    });
    @Inject
    private Provider<AdvancedUserLoginDialog> advancedUserLoginDialogProvider;
    @Inject
    private FXMLLoader loader;
    @Inject
    private TaskThread tt;

    private GeniUser loggedInUser;

    public static void main(String[] args) {
        for (String arg : args) {
            if (arg.equalsIgnoreCase("debug") || arg.equalsIgnoreCase("--debug") || arg.equalsIgnoreCase("-debug"))
                debugEnabled = true;
        }
        launch(args);
    }

    @Override
    public void start(final Stage stage) throws Exception {
        Thread.setDefaultUncaughtExceptionHandler(UncaughtGuiExceptionLogger.getInstance(stage));
        context.init();

        loggedInUser = advancedUserLoginDialogProvider.get().showUserLogin(stage);
        if (isUserLoggedIn())
            showAutomatedTester(stage);
        else
            exit();
    }

    private void showAutomatedTester(Stage stage) {
        stage.setTitle("jFed Automated Tester");

        try {
            loader.setLocation(AutomatedTesterStandalone.class.getResource(AUTOMATED_TESTER_FXML));
            stage.setScene(new Scene(loader.load()));

            stage.setOnCloseRequest(event -> exit());

            stage.show();
        } catch (IOException e) {
            LOG.error("Error while loading jFed Automated Tester", e);
        }

    }

    public void exit() {
        LOG.info("Close was requested. Trying to terminate");
        tt.requestStop();

        //stop any running ssh-agent
        SshAgentHelper.stopSshAgent();

        Platform.exit();
        System.exit(0);
    }

    @Override
    public GeniUser getLoggedInGeniUser() {
        return loggedInUser;
    }

    @Override
    public boolean isUserLoggedIn() {
        return loggedInUser != null;
    }
}
