package com.alexrnl.commons.arguments;

import java.lang.reflect.Field;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.logging.Logger;

import com.alexrnl.commons.utils.object.ReflectUtils;

/**
 * Class which allow to parse string arguments and store them in a target object.
 * @author Alex
 */
public class Arguments {
	/** Logger */
	private static Logger			lg	= Logger.getLogger(Arguments.class.getName());
	
	/** The name of the program. */
	private final String				programName;
	/** The object which holds the target */
	private final Object				target;
	/** The list of parameters in the target */
	private final SortedSet<Parameter>	parameters;
	
	
	/**
	 * Constructor #1.<br />
	 * @param programName
	 *        the name of the program.
	 * @param target
	 *        the object which holds the target.
	 */
	public Arguments (final String programName, final Object target) {
		super();
		this.programName = programName;
		this.target = target;
		this.parameters = retrieveParameters(target);
	}
	
	/**
	 * Parse and build a list with the parameters field marked with the {@link Param} annotation in
	 * the object specified.
	 * @param obj
	 *        the object to parse for parameters.
	 * @return the list of parameters associated to this object.
	 */
	private static SortedSet<Parameter> retrieveParameters (final Object obj) {
		final SortedSet<Parameter> params = new TreeSet<>();
		for (final Field field : ReflectUtils.retrieveFields(obj.getClass(), Param.class)) {
			field.setAccessible(true);
			params.add(new Parameter(field, field.getAnnotation(Param.class)));
		}
		return params;
	}
	
	/**
	 * Parse the arguments and set the target in the target object.
	 * @param arguments
	 *        the arguments to parse.
	 */
	public void parse (final String... arguments) {
		parse(arguments);
	}
	
	/**
	 * Parse the arguments and set the target in the target object.
	 * @param arguments
	 *        the arguments to parse.
	 */
	public void parse (final Iterable<String> arguments) {
		// TODO
	}
	
	/**
	 * Display the parameter's usage on the standard output.
	 */
	public void usage () {
		System.out.println(this);
	}
	
	@Override
	public String toString () {
		// TODO
		return "";
	}
}

@@ -153,16 +153,62 @@
 ogger;%0A%0A
+import com.alexrnl.commons.utils.StringUtils;%0A
 import c
@@ -253,16 +253,16 @@
 tUtils;%0A
-
 %0A/**%0A * 
@@ -425,16 +425,17 @@
 ogger%09%09%09
+%09
 lg%09= Log
@@ -478,16 +478,89 @@
 e());%0A%09%0A
+%09/** The tab character */%0A%09private static final Character%09%09TAB%09= '%5Ct';%0A%09%0A
 %09/** The
@@ -734,32 +734,32 @@
 n the target */%0A
+
 %09private final S
@@ -792,18 +792,16 @@
 ters;%0A%09%0A
-%09%0A
 %09/**%0A%09 *
@@ -2322,27 +2322,473 @@
 %7B%0A%09%09
-// TODO%0A%09%09return %22%22
+final StringBuilder usage = new StringBuilder(programName + %22 usage as follow:%22);%0A%09%09for (final Parameter param : parameters) %7B%0A%09%09%09usage.append(TAB);%0A%09%09%09if (!param.isRequired()) %7B%0A%09%09%09%09usage.append('%5B');%0A%09%09%09%7D else %7B%0A%09%09%09%09usage.append(' ');%0A%09%09%09%7D%0A%09%09%09usage.append(%22  %22).append(StringUtils.separateWith(%22, %22, param.getNames()));%0A%09%09%09int nbTabs = 4;%0A%09%09%09while (nbTabs-- %3E 0) %7B%0A%09%09%09%09usage.append(TAB);%0A%09%09%09%7D%0A%09%09%09usage.append(param.getDescription());%0A%09%09%7D%0A%09%09return usage.toString()
 ;%0A%09%7D

Implement Arguments#usage() method