package com.sysdeo.eclipse.tomcat;

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

/**
 * container for managing a number of WebClassPathEntry objects
 *
 * @version 	1.0
 * @author		Martin Kahr
 */
public class WebClassPathEntries {

	/** TAG_NAME */
	public static final String TAG_NAME = "webClassPathEntries";
	/** ENTRY_TAG_NAME */
	private static final String ENTRY_TAG_NAME = "webClassPathEntry";

	/** entries */
	private final List<String> entries;

	/**
	 * Constructor
	 */
	public WebClassPathEntries() {
		this(new ArrayList<String>());
	}

	/**
	 * Constructor
	 *
	 * @param values List
	 */
	public WebClassPathEntries(final List<String> values) {
		this.entries = values;
	}

	/**
	 * returns the number of webclasspath-entries
	 * @return size
	 */
	public int size() {
		return this.entries.size();
	}

	/**
	 * @param index int
	 * @return the WebClassPathEntry value at the index provided
	 */
	public String getWebClassPathEntry(final int index) {
		if (index >= this.entries.size()) {
			return null;
		}
		String entry = this.entries.get(index);
		return entry;
	}

	/**
	 * add a WebClassPathEntry value
	 * @param value String
	 */
	public void addWebClassPathEntry(final String value) {
		if (this.entries.contains(value)) {
			return;
		}
		this.entries.add(value);
	}

	/**
	 *
	 * @return list
	 */
	public List<String> getList() {
		return this.entries;
	}

	/**
	 * transfer the state of this object to an XML string
	 * @return String
	 */
	public String xmlMarshal() {
		return xmlMarshal(0);
	}

	/**
	 *
	 * @param spacesToIntend int
	 * @return String
	 */
	public String xmlMarshal(final int spacesToIntend) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < spacesToIntend; i++) {
			sb.append(" ");
		}
		String spaces = sb.toString();

		StringBuilder xml = new StringBuilder(spaces);
		xml.append(startTag()).append("\n");
		for (final String entry : this.entries) {
			xml.append(spaces).append(spaces).append(startEntryTag());
			xml.append(entry);
			xml.append(endEntryTag()).append("\n");
		}
		xml.append(spaces).append(endTag()).append("\n");
		return xml.toString();
	}

	/**
	 * instantiate a WebClassPathEntries object and intialize
	 * it with the xml data provided
	 * @param xmlString xml
	 * @return the object if unmarshaling had no errors. returns null
	 *          if the marshaling was unsuccessfully.
	 */
	public static WebClassPathEntries xmlUnmarshal(final String xmlString) {
		if (xmlString == null || xmlString.trim().isEmpty()) {
			return null;
		}

		int start = xmlString.indexOf(startTag());
		int end   = xmlString.indexOf(endTag());
		if (start < 0 || end <= start) {
			return null;
		}

		String value = xmlString.substring(start + startTag().length(), end);
		value = value.trim();

		WebClassPathEntries webEntries = new WebClassPathEntries();
		while (value != null && !value.isEmpty()) {
			start = value.indexOf(startEntryTag());
			end   = value.indexOf(endEntryTag());
			if (0 <= start || start < end) {
				String entryValue = value.substring(start + startEntryTag().length(), end);
				if (!entryValue.trim().isEmpty()) {
					webEntries.addWebClassPathEntry(entryValue);
				}
				value = value.substring(end + endEntryTag().length());
			} else {
				value = null;
			}
		}

		return webEntries;
	}

	/**
	 * startTag
	 * @return startTag
	 */
	private static String startTag() {
		return "<" + TAG_NAME + ">";
	}

	/**
	 * endTag
	 * @return endTag
	 */
	private static String endTag() {
		return "</" + TAG_NAME + ">";
	}

	/**
	 * startEntryTag
	 * @return startEntryTag
	 */
	private static String startEntryTag() {
		return "<" + ENTRY_TAG_NAME + ">";
	}

	/**
	 * endEntryTag
	 * @return endEntryTag
	 */
	private static String endEntryTag() {
		return "</" + ENTRY_TAG_NAME + ">";
	}
}
