package com.github.sbugat.ec2tools.service.options;

import gnu.getopt.Getopt;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.ext.XLogger;
import org.slf4j.ext.XLoggerFactory;

import com.github.sbugat.ec2tools.EC2StartStopMain;

public class ProgramOptionsService {

	/*** SLF4J XLogger. */
	private static final XLogger LOG = XLoggerFactory.getXLogger(ProgramOptionsService.class);

	private static final String USAGE = "Usage: [-l] [-e|-c|-p -s <section1> -s <section2> ... ]";
	private static final String USAGE_LIST = "[-l]: list configuration ";
	private static final String USAGE_EXECUTE = "[-e]: execute sections orders";
	private static final String USAGE_CHECK = "[-c]: check if sections orders can be done";
	private static final String USAGE_POST_CHECK = "[-p]: check if sections orders has been done";
	private static final String USAGE_SECTIONS = "[-s <section1> -s <section2> ... ]: sections to process";

	public ProgramOptions processProgramArgs(final String programArgs[]) {

		// Arguments checking
		final Getopt getOpt = new Getopt(EC2StartStopMain.class.getSimpleName(), programArgs, ":lecps:");
		getOpt.setOpterr(false);

		boolean list = false;
		boolean check = false;
		boolean execute = false;
		boolean postCheck = false;
		int exclusiveOptionsCount = 0;
		final List<String> sectionsToExecute = new ArrayList<String>();

		int option = getOpt.getopt();
		while (-1 != option) {

			switch (option) {

			case 'l':
				list = true;
				exclusiveOptionsCount++;
				break;

			case 'e':
				execute = true;
				exclusiveOptionsCount++;
				break;

			case 'c':
				check = true;
				exclusiveOptionsCount++;
				break;

			case 'p':
				postCheck = true;
				exclusiveOptionsCount++;
				break;

			case 's':
				sectionsToExecute.add(getOpt.getOptarg());
				break;

			case '?':
			default:
				System.err.println(getUsage());
				final IllegalArgumentException exception = new IllegalArgumentException("Unknow option:" + option);
				LOG.exit(exception);
				throw exception;
			}

			option = getOpt.getopt();
		}

		// Missing a mandatory option
		if (0 == exclusiveOptionsCount) {
			System.err.println(getUsage());
			final IllegalArgumentException exception = new IllegalArgumentException("One of list, execute, check and post-check options is mandatory ");
			LOG.exit(exception);
			throw exception;
		}
		// Multiple exclusive options
		else if (exclusiveOptionsCount > 1) {
			System.err.println(getUsage());
			final IllegalArgumentException exception = new IllegalArgumentException("List, execute, check and post-check options are exclusive");
			LOG.exit(exception);
			throw exception;
		}
		// Missing section option
		else if (sectionsToExecute.isEmpty() && !list) {

			System.err.println(getUsage());
			final IllegalArgumentException exception = new IllegalArgumentException("Execute, check and post-check options need one or more section option");
			LOG.exit(exception);
			throw exception;
		}
		// No getopt options
		else if (getOpt.getOptind() < programArgs.length) {

			System.err.println(getUsage());
			final IllegalArgumentException exception = new IllegalArgumentException("Non-option argument detected, check the usage and all arguments");
			LOG.exit(exception);
			throw exception;
		}

		// All check are OK
		final ProgramOptions programOptions = new ProgramOptions(execute, list, check, postCheck, sectionsToExecute);
		LOG.exit(programOptions);
		return programOptions;
	}

	/**
	 * Return the usage multi-line String to display
	 * 
	 * @return usage multi-line String
	 */
	public String getUsage() {
		final StringBuilder usage = new StringBuilder(USAGE);
		usage.append(System.lineSeparator());
		usage.append(USAGE_LIST);
		usage.append(System.lineSeparator());
		usage.append(USAGE_EXECUTE);
		usage.append(System.lineSeparator());
		usage.append(USAGE_CHECK);
		usage.append(System.lineSeparator());
		usage.append(USAGE_POST_CHECK);
		usage.append(System.lineSeparator());
		usage.append(USAGE_SECTIONS);
		return usage.toString();
	}
}

@@ -246,16 +246,112 @@
 pMain;%0A%0A
+/**%0A * Service to load program arguments as valid options.%0A * %0A * @author Sylvain Bugat%0A * %0A */%0A
 public c
@@ -497,16 +497,41 @@
 lass);%0A%0A
+%09/** Main usage line. */%0A
 %09private
@@ -618,16 +618,43 @@
 ... %5D%22;%0A
+%09/** List option usage. */%0A
 %09private
@@ -716,16 +716,46 @@
 tion %22;%0A
+%09/** Execute option usage. */%0A
 %09private
@@ -824,16 +824,44 @@
 rders%22;%0A
+%09/** Check option usage. */%0A
 %09private
@@ -933,32 +933,65 @@
 s can be done%22;%0A
+%09/** Post-check option usage. */%0A
 %09private static 
@@ -1070,16 +1070,47 @@
  done%22;%0A
+%09/** Sections option usage. */%0A
 %09private
@@ -1207,16 +1207,142 @@
 cess%22;%0A%0A
+%09/**%0A%09 * Process all program arguments.%0A%09 * %0A%09 * @param programArgs program arguments%0A%09 * @return loaded program options%0A%09 */%0A
 %09public 
@@ -1387,16 +1387,18 @@
 l String
+%5B%5D
  program
@@ -1401,18 +1401,16 @@
 gramArgs
-%5B%5D
 ) %7B%0A%0A%09%09/
@@ -3908,16 +3908,17 @@
  display
+.
 %0A%09 * %0A%09 

Add comments