/*
 * Copyright 2012 The Clustermeister Team.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.nethad.clustermeister.provisioning.cli;

import com.google.common.annotations.VisibleForTesting;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.logging.LogManager;
import jline.ConsoleReader;
import jline.SimpleCompletor;
import org.apache.commons.cli.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author thomas
 */
public class ProvisioningCLI {

    private final Logger logger = LoggerFactory.getLogger(ProvisioningCLI.class);

    private static final String OPTION_CONFIG_FILE = "config";
    private static final String DEFAULT_CONFIG_FILE = System.getProperty("user.home") + "/.clustermeister/configuration.properties";
    private static final String OPTION_PROVIDER = "provider";
    private static final String DEFAULT_PROVIDER = "torque";

    public static void main(String... args) {
        loadJDKLoggingConfiguration();
        new ProvisioningCLI().startCLI(args);
    }
    private String configFilePath;
    private Options options;
    private Provider provider;
    private Provisioning provisioning;
    private UserInputEvaluation userInputEvaluation;

    private static void loadJDKLoggingConfiguration() {
        try {
            LogManager.getLogManager().readConfiguration(
                    ProvisioningCLI.class.getResourceAsStream("/jdk-logging.properties"));
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (SecurityException ex) {
            ex.printStackTrace();
        }
    }
    
    protected void startCLI(String[] args) {
//        if (args.length == 0) {
//            HelpFormatter formatter = new HelpFormatter();
//            formatter.printHelp( "clustermeister", getOptions());
//        } else {
            try {
                parseArguments(args);
                logger.info("Using configuration in "+configFilePath);
                logger.info("Using provider "+provider);
                provisioning = new Provisioning(configFilePath, provider);
                provisioning.execute();
                startREPL();
            } catch (ParseException ex) {
                logger.error("Terminated.", ex);
            }
//        }
        // TODO this is necessary because JPPFClient still has running threads which 
        // won't shut down with close().
        System.exit(0);
    }
    
    private void startREPL() {
        try {
            userInputEvaluation = new UserInputEvaluation(provisioning);
            ConsoleReader reader = new ConsoleReader();
            reader.setBellEnabled(false);
            reader.addCompletor(new SimpleCompletor(userInputEvaluation.commands()));

            PrintWriter out = new PrintWriter(System.out);
            String line;
            while ((line = reader.readLine("cm$ ")) != null) {
                userInputEvaluation.evaluate(line);
                if (line.equalsIgnoreCase("quit") || line.equalsIgnoreCase("exit")) {
                    break;
                }
                out.flush();
            }
        } catch (Exception ex) {
            logger.warn("Exception", ex);
        }
    }

//    private String nextUserInput() {
//        System.out.print("cm$ ");
//        BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
//        while (true) {
//            try {
//                return userInput.readLine();
//            } catch (IOException ex) {
//                logger.error("Could not read user input.", ex);
//            }
//            return nextUserInput();
//        }
//    }

    protected void parseArguments(String[] args) throws ParseException {
        CommandLineParser parser = new PosixParser();
        CommandLine cmd = parser.parse(getOptions(), args);
        configFilePath = cmd.getOptionValue(OPTION_CONFIG_FILE, DEFAULT_CONFIG_FILE);
        provider = Provider.fromString(cmd.getOptionValue(OPTION_PROVIDER, DEFAULT_PROVIDER));
    }

    private Options getOptions() {
        if (options == null) {
            options = new Options();
            options.addOption("c", OPTION_CONFIG_FILE, true, "define the path to your configuration.properties, default: "+DEFAULT_CONFIG_FILE);
            options.addOption("p", OPTION_PROVIDER, true, "specify the provider to use, either 'amazon' or 'torque', default: "+DEFAULT_PROVIDER);
        }
        return options;
    }
    
    @VisibleForTesting
    protected String getConfigFilePath() {
        return configFilePath;
    }
    
    @VisibleForTesting
    protected Provider getProvider() {
        return provider;
    }


}

@@ -1165,24 +1165,78 @@
 LI.class);%0A%0A
+    private static final String OPTION_HELP = %22help%22;%0A
     private 
@@ -2243,24 +2243,54 @@
     %7D%0A    %7D%0A
+    private boolean showHelp;%0A
     %0A    pro
@@ -2327,26 +2327,24 @@
 args) %7B%0A
-//
         
 if (args
@@ -2339,34 +2339,18 @@
     
-if (args.length == 0)
+    try
  %7B%0A
-//
     
@@ -2361,57 +2361,35 @@
     
-HelpFormatter formatter = new HelpFormatter();%0A//
+    parseArguments(args);%0A 
     
@@ -2400,72 +2400,64 @@
     
-formatter.printHelp( %22clustermeister%22, getOptions()
+   if (showHelp) %7B%0A                    usage(
 );%0A
-//
         
 %7D el
@@ -2456,17 +2456,8 @@
     
-%7D else %7B%0A
     
@@ -2456,37 +2456,39 @@
                 
-try %7B
+return;
 %0A               
@@ -2488,37 +2488,17 @@
         
-parseArguments(args);
+%7D
 %0A       
@@ -3031,24 +3031,162 @@
 it(0);%0A    %7D
+%0A%0A    private void usage() %7B%0A        HelpFormatter formatter = new HelpFormatter();%0A        formatter.printHelp(%22cli.jar%22, options);%0A    %7D
 %0A    %0A    pr
@@ -4570,24 +4570,71 @@
 s(), args);%0A
+        showHelp = cmd.hasOption(OPTION_HELP);%0A
         conf
@@ -4908,24 +4908,104 @@
  Options();%0A
+            options.addOption(%22h%22, OPTION_HELP, false, %22show this help text.%22);%0A
             

add --help to command line client