package net.ssehub.kernel_haven;

import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;

import net.ssehub.kernel_haven.config.Configuration;
import net.ssehub.kernel_haven.config.DefaultSettings;
import net.ssehub.kernel_haven.util.Logger;
import net.ssehub.kernel_haven.util.Util;

/**
 * 
 * Class for loading a configuration and starting the PipelineConfigurator.
 * 
 * @author Moritz
 * @author Marvin
 * @author Kevin
 *
 */
public class Run {

    private static final Logger LOGGER;

    static {
        Logger.init();
        LOGGER = Logger.get();
    }
    
    /**
     * Prints some information about the system to the log.
     */
    private static void printSystemInfo() {
        Properties properties = System.getProperties();
        
        List<String> lines = new LinkedList<>();
        lines.add("System Info:");
        
        String[][] relevantKeys = {
            // key, visible name
            {"os.name", "OS Name"},
            {"os.version", "OS Version"},
            {"os.arch", "OS Arch"},
            {"java.home", "Java Home"},
            {"java.vendor", "Java Vendor"},
            {"java.version", "Java Version"},
            {"java.vm.name", "Java VM Name"},
            {"java.vm.version", "Java VM Version"},
            {"java.vm.vendor", "Java VM Vendor"},
            {"user.dir", "Working Directory"},
            {"java.io.tmpdir", "Temporary Directory"},
            {"file.encoding", "File Encoding"},
            {"java.class.path", "Java Class Path"},
        };
        
        for (String[] key : relevantKeys) {
            if (properties.containsKey(key[0])) {
                lines.add("\t" + key[1] + " = " + properties.get(key[0]));
            }
        }
        
        Runtime runtime = Runtime.getRuntime();
        lines.add("\tMaximum Memory: " + Util.formatBytes(runtime.maxMemory()));
        lines.add("\tAvailable Processors: " + runtime.availableProcessors());
        
        LOGGER.logInfo(lines.toArray(new String[] {}));
    }

    /**
     * Main method to execute the Pipeline defined in the the properties file.
     *
     * 
     * @param args
     *            the command line arguments. Used for parsing property-file
     *            location and flags.
     */
    public static void main(String... args) {
        Thread.currentThread().setName("Setup");
        
        Thread.setDefaultUncaughtExceptionHandler((Thread thread, Throwable exc) -> {
            LOGGER.logException("Unhandled exception in thread " + thread.getName(), exc);
        });

        File propertiesFile = null;

        boolean archiveParam = false;

        for (String arg : args) {
            if (arg.equals("--archive")) {
                archiveParam = true;
            } else if (!arg.startsWith("--")) {
                if (propertiesFile == null) {
                    propertiesFile = new File(arg);
                } else {
                    LOGGER.logError("You must not define more than one properties file");
                    System.exit(1);
                }

            } else {
                LOGGER.logError("Unknown command line option " + arg);
                System.exit(1);
            }
        }

        if (propertiesFile == null) {
            LOGGER.logError("No properties-file provided. Stopping system");
            System.exit(1);
        }

        Configuration config = null;

        try {
            config = new Configuration(propertiesFile);
            DefaultSettings.registerAllSettings(config);

            if (archiveParam) {
                config.setValue(DefaultSettings.ARCHIVE, true);
            }

            PipelineConfigurator.instance().init(config);

        } catch (SetUpException e) {
            LOGGER.logError("Invalid configuration detected:", e.getMessage());
            System.exit(1);
        }
        try {
            LOGGER.setup(config);

        } catch (SetUpException exc) {
            LOGGER.logException(
                    "Was not able to setup the Logger as defined in the properties. Logging now to Console only", exc);
        }
        
        LOGGER.logInfo("Start executing KernelHaven with configuration file " + propertiesFile.getPath());
        printSystemInfo();

        PipelineConfigurator.instance().execute();
    }
}

@@ -2293,25 +2293,132 @@
 lags.%0A     *
-/
+ @return Whether run was successful or not.%0A     */%0A    // CHECKSTYLE:OFF // ignore %22too many returns%22 error
 %0A    public 
@@ -2428,16 +2428,18 @@
 tic 
-void mai
+boolean ru
 n(St
@@ -2446,32 +2446,53 @@
 ring... args) %7B%0A
+    // CHECKSTYLE:ON%0A
         Thread.c
@@ -3190,38 +3190,36 @@
             
-System.exit(1)
+return false
 ;%0A          
@@ -3331,38 +3331,36 @@
             
-System.exit(1)
+return false
 ;%0A          
@@ -3497,38 +3497,36 @@
             
-System.exit(1)
+return false
 ;%0A        %7D%0A
@@ -3995,22 +3995,20 @@
     
-System.exit(1)
+return false
 ;%0A  
@@ -4465,12 +4465,438 @@
 ();%0A    
-%7D
+    return true;%0A    %7D%0A    %0A    /**%0A     * Main method to execute the Pipeline defined in the the properties file.%0A     *%0A     * %0A     * @param args%0A     *            the command line arguments. Used for parsing property-file%0A     *            location and flags.%0A     */%0A    public static void main(String... args) %7B%0A        boolean success = run(args);%0A        if (!success) %7B%0A            System.exit(1);%0A        %7D%0A    %7D%0A    
 %0A%7D%0A

Add boolean run(String... args) to Run