package org.bench4q.agent.utils;

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

import org.bench4q.agent.utils.types.Table;

/**
 * 
 * @author coderfengyun
 * 
 */
public abstract class ParameterParser {
	private static final String RadioGroup_SEPARATOR = ";";
	private static final String NFIELD_SEPARATOR = RadioGroup_SEPARATOR;

	static public List<String> buildNField(String value) {
		List<String> result = new LinkedList<String>();
		List<String> realTokens = getRealTokens(NFIELD_SEPARATOR, value, false);
		for (String token : realTokens) {
			result.add(token.trim());
		}
		return result;
	}

	static public String buildRadioGroup(String value) {
		List<String> realTokens = getRealTokens(RadioGroup_SEPARATOR, value,
				false);
		if (realTokens.size() == 0) {
			return "";
		} else {
			return unescape(realTokens.get(0));
		}
	}

	static public List<String> buildCheckBox(String value) {
		return buildNField(value);
	}

	static public String buildCombo(String value) {
		return buildRadioGroup(value);
	}

	static public Table buildTable(String value, List<String> columnLables) {
		return Table.buildTable(value, columnLables);
	}

	/**
	 * Get the number of escape character in the end of the string
	 * 
	 * @param value
	 *            The string to be analyzed
	 * @return 0 if no escape character was found, else the number
	 */
	private static int getNumberOfEscapeCharacter(String value) {
		int result = 0;
		if (value.length() > 0) {
			int last = value.lastIndexOf(ParameterConstant.escape);
			if (last == value.length() - 1) {
				result = 1 + getNumberOfEscapeCharacter(value
						.substring(0, last));
			}
		}
		return result;
	}

	/**
	 * Split the string value with the separator, and check if there is no
	 * escape character before the separator
	 * 
	 * @param separator
	 *            The separator
	 * @param value
	 *            The string value to be split
	 * @return The vector containing each token
	 */
	public static List<String> getRealTokens(String separator, String value,
			boolean toUnescapeSeparator) {
		List<String> result = new ArrayList<String>();
		for (String entry : value.split(separator)) {
			if (getNumberOfEscapeCharacter(entry) % 2 != 0) {
				if (toUnescapeSeparator) {
					entry = entry.substring(0, entry.length() - 1)
							+ unescape(separator);
				} else {
					entry = entry.substring(0, entry.length() - 1) + separator;
				}
			}
			if (entry.isEmpty())
				continue;
			result.add(entry);
		}
		return result;
	}

	/**
	 * Replaces every escape sequences by the corresponding original character
	 * 
	 * @param value
	 *            the string where some characters are escaped by '\' character
	 * @return the unescaped string
	 */
	public static String unescape(String value) {
		StringBuilder result = new StringBuilder();
		char c;
		boolean escape = false; // escape sequence
		for (int i = 0; i < value.length(); ++i) {
			c = value.charAt(i);
			if (escape) {
				result.append(c);
				escape = false;
			} else {
				if (c == ParameterConstant.escape.charAt(0)) {
					escape = true;
				} else {
					result.append(c);
				}
			}
		}
		return result.toString();
	}
}
