package org.apache.mesos.elasticsearch.scheduler;

import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;

import java.lang.ref.WeakReference;

/**
 * Application which starts the Elasticsearch scheduler
 */
public class Main {

    public static final String NUMBER_OF_HARDWARE_NODES = "n";

    public static final String ZK_HOST = "zk";

    private Options options;

    private Configuration configuration;

    public Main() {
        this.options = new Options();
        this.options.addOption(NUMBER_OF_HARDWARE_NODES, "numHardwareNodes", true, "number of hardware nodes");
        this.options.addOption(ZK_HOST, "ZookeeperNode", true, "Zookeeper IP address and port");
    }

    public static void main(String[] args) {
        Main main = new Main();
        main.run(args);
    }

    public void run(String[] args) {
        parseCommandlineOptions(args);

        final ElasticsearchScheduler scheduler = new ElasticsearchScheduler(configuration, new TaskInfoFactory());

        WebApplication.elasticsearchScheduler = new WeakReference<>(scheduler);
        SpringApplication.run(WebApplication.class, args);

        scheduler.run();
    }

    private void parseCommandlineOptions(String[] args) {
        configuration = new Configuration();
        WebApplication.configuration = new WeakReference<>(configuration);

        try {
            CommandLineParser parser = new BasicParser();
            CommandLine cmd = parser.parse(options, args);

            String numberOfHwNodesString = cmd.getOptionValue(NUMBER_OF_HARDWARE_NODES);
            String zkHost = cmd.getOptionValue(ZK_HOST);

            if (numberOfHwNodesString == null || zkHost == null) {
                printUsage();
                return;
            }

            configuration.setNumberOfHwNodes(Integer.parseInt(numberOfHwNodesString));
            configuration.setZookeeperHost(zkHost);
            configuration.setState(new State(new ZooKeeperStateInterfaceImpl(zkHost + ":" + configuration.getZookeeperPort())));
        } catch (ParseException | IllegalArgumentException e) {
            printUsage();
        }
    }

    private void printUsage() {
        HelpFormatter formatter = new HelpFormatter();
        formatter.printHelp(configuration.getFrameworkName(), options);
    }

}

@@ -363,192 +363,8 @@
 ion;
-%0Aimport org.springframework.boot.autoconfigure.EnableAutoConfiguration;%0Aimport org.springframework.context.annotation.Bean;%0Aimport org.springframework.context.annotation.ComponentScan;
 %0A%0Aim
@@ -1093,16 +1093,32 @@
 %0A       
+ configuration =
  parseCo
@@ -1254,24 +1254,99 @@
 actory());%0A%0A
+        WebApplication.configuration = new WeakReference%3C%3E(configuration);%0A
         WebA
@@ -1413,24 +1413,25 @@
 duler);%0A
+%0A
         
 SpringAp
@@ -1422,16 +1422,22 @@
         
+final 
 SpringAp
@@ -1449,35 +1449,152 @@
 tion
-.run(WebApplication.class, 
+ springApplication = new SpringApplication(WebApplication.class);%0A        springApplication.setShowBanner(false);%0A        springApplication.run(
 args
@@ -1641,20 +1641,29 @@
 private 
-void
+Configuration
  parseCo
@@ -1708,68 +1708,22 @@
     
-configuration = new Configuration();%0A        WebApplication.
+Configuration 
 conf
@@ -1738,33 +1738,17 @@
 n = new 
-WeakReference%3C%3E(c
+C
 onfigura
@@ -1751,16 +1751,17 @@
 guration
+(
 );%0A%0A    

Remove Spring Boot banner and streamline singleton bean creations