/*******************************************************************************
 * Copyright (c) 2010-2011 Composent, Inc. and others. All rights reserved. This
 * program and the accompanying materials are made available under the terms of
 * the Eclipse Public License v1.0 which accompanies this distribution, and is
 * available at http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Composent, Inc. - initial API and implementation
 ******************************************************************************/
package org.eclipse.ecf.internal.osgi.services.remoteserviceadmin;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class EndpointDescriptionParser {

	private static List<String> multiValueTypes;

	static {
		multiValueTypes = Arrays.asList(new String[] { "String", "Long", //$NON-NLS-1$ //$NON-NLS-2$
				"long", "Double", "double", "float", "Float", "int", "Integer", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
				"byte", "Byte", "char", "Character", "boolean", "Boolean", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
				"short", "Short" }); //$NON-NLS-1$ //$NON-NLS-2$
	}

	private static final String ENDPOINT_DESCRIPTIONS = "endpoint-descriptions"; //$NON-NLS-1$
	private static final String ENDPOINT_DESCRIPTION = "endpoint-description"; //$NON-NLS-1$
	private static final String ENDPOINT_PROPERTY = "property"; //$NON-NLS-1$
	private static final String ENDPOINT_PROPERTY_NAME = "name"; //$NON-NLS-1$
	private static final String ENDPOINT_PROPERTY_VALUE = "value"; //$NON-NLS-1$
	private static final String ENDPOINT_PROPERTY_VALUETYPE = "value-type"; //$NON-NLS-1$
	private static final String ENDPOINT_PROPERTY_ARRAY = "array"; //$NON-NLS-1$
	private static final String ENDPOINT_PROPERTY_LIST = "list"; //$NON-NLS-1$
	private static final String ENDPOINT_PROPERTY_SET = "set"; //$NON-NLS-1$
	private static final String ENDPOINT_PROPERTY_XML = "xml"; //$NON-NLS-1$

	public static String[] noAttributes = new String[0];

	private XMLReader xmlReader;

	class IgnoringHandler extends AbstractHandler {
		public IgnoringHandler(AbstractHandler parent) {
			super(parent);
			this.elementHandled = "IgnoringAll"; //$NON-NLS-1$
		}

		public void startElement(String name, Attributes attributes) {
			noSubElements(name, attributes);
		}
	}

	/**
	 * Abstract base class for content handlers
	 */
	abstract class AbstractHandler extends DefaultHandler {

		protected ContentHandler parentHandler = null;
		protected String elementHandled = null;

		protected StringBuffer characters = null; // character data inside an
													// element

		public AbstractHandler() {
			// Empty constructor for a root handler
		}

		public AbstractHandler(ContentHandler parentHandler) {
			this.parentHandler = parentHandler;
			xmlReader.setContentHandler(this);
		}

		public AbstractHandler(ContentHandler parentHandler,
				String elementHandled) {
			this.parentHandler = parentHandler;
			xmlReader.setContentHandler(this);
			this.elementHandled = elementHandled;
		}

		public void startElement(String uri, String localName, String qName,
				Attributes attributes) throws SAXException {
			finishCharacters();
			String name = makeSimpleName(localName, qName);
			startElement(name, attributes);
		}

		public abstract void startElement(String name, Attributes attributes)
				throws SAXException;

		public void invalidElement(String name, Attributes attributes) {
			unexpectedElement(this, name, attributes);
			new IgnoringHandler(this);
		}

		public void endElement(String namespaceURI, String localName,
				String qName) {
			finishCharacters();
			finished();
			// Restore the parent content handler
			xmlReader.setContentHandler(parentHandler);
		}

		/**
		 * An implementation for startElement when there are no sub-elements
		 */
		protected void noSubElements(String name, Attributes attributes) {
			unexpectedElement(this, name, attributes);
			// Create a new handler to ignore subsequent nested elements
			new IgnoringHandler(this);
		}

		/*
		 * Save up character data until endElement or nested startElement
		 * 
		 * @see org.xml.sax.ContentHandler#characters
		 */
		public void characters(char[] chars, int start, int length) {
			if (this.characters == null) {
				this.characters = new StringBuffer();
			}
			this.characters.append(chars, start, length);
		}

		// Consume the characters accumulated in this.characters.
		// Called before startElement or endElement
		private String finishCharacters() {
			// common case -- no characters or only whitespace
			if (this.characters == null || this.characters.length() == 0) {
				return null;
			}
			if (allWhiteSpace(this.characters)) {
				this.characters.setLength(0);
				return null;
			}

			// process the characters
			try {
				String trimmedChars = this.characters.toString().trim();
				if (trimmedChars.length() == 0) {
					// this shouldn't happen due to the test for allWhiteSpace
					// above
					System.err.println("Unexpected non-whitespace characters: " //$NON-NLS-1$
							+ trimmedChars);
					return null;
				}
				processCharacters(trimmedChars);
				return trimmedChars;
			} finally {
				this.characters.setLength(0);
			}
		}

		// Method to override in the handler of an element with CDATA.
		protected void processCharacters(String data) {
			if (data.length() > 0)
				unexpectedCharacterData(this, data);
		}

		private boolean allWhiteSpace(StringBuffer sb) {
			int length = sb.length();
			for (int i = 0; i < length; i += 1)
				if (!Character.isWhitespace(sb.charAt(i)))
					return false;
			return true;
		}

		/**
		 * Called when this element and all elements nested into it have been
		 * handled.
		 */
		protected void finished() {
			// Do nothing by default
		}

		/*
		 * A name used to identify the handler.
		 */
		public String getName() {
			return (elementHandled != null ? elementHandled : "NoName"); //$NON-NLS-1$
		}

		/**
		 * Parse the attributes of an element with only required attributes.
		 */
		protected String[] parseRequiredAttributes(Attributes attributes,
				String[] required) {
			return parseAttributes(attributes, required, noAttributes);
		}

		/**
		 * Parse the attributes of an element with a single optional attribute.
		 */
		protected String parseOptionalAttribute(Attributes attributes,
				String name) {
			return parseAttributes(attributes, noAttributes,
					new String[] { name })[0];
		}

		/**
		 * Parse the attributes of an element, given the list of required and
		 * optional ones. Return values in same order, null for those not
		 * present. Log warnings for extra attributes or missing required
		 * attributes.
		 */
		protected String[] parseAttributes(Attributes attributes,
				String[] required, String[] optional) {
			String[] result = new String[required.length + optional.length];
			for (int i = 0; i < attributes.getLength(); i += 1) {
				String name = attributes.getLocalName(i);
				String value = attributes.getValue(i).trim();
				int j;
				if ((j = indexOf(required, name)) >= 0)
					result[j] = value;
				else if ((j = indexOf(optional, name)) >= 0)
					result[required.length + j] = value;
				else
					unexpectedAttribute(elementHandled, name, value);
			}
			for (int i = 0; i < required.length; i += 1)
				checkRequiredAttribute(elementHandled, required[i], result[i]);
			return result;
		}

	}

	SAXParser getParser() throws ParserConfigurationException, SAXException {
		Activator a = Activator.getDefault();
		if (a == null)
			return null;

		SAXParserFactory factory = a.getSAXParserFactory();
		if (factory == null)
			throw new SAXException("Unable to acquire sax parser"); //$NON-NLS-1$
		factory.setNamespaceAware(true);
		factory.setValidating(false);
		try {
			factory.setFeature(
					"http://xml.org/sax/features/string-interning", true); //$NON-NLS-1$
		} catch (SAXException se) {
			// some parsers may not support string interning
		}
		SAXParser theParser = factory.newSAXParser();
		if (theParser == null) {
			throw new SAXException("Unable to create sax parser"); //$NON-NLS-1$
		}
		xmlReader = theParser.getXMLReader();
		return theParser;
	}

	abstract class RootHandler extends AbstractHandler {

		public RootHandler() {
			super();
		}

		public void initialize(DocHandler document, String rootName,
				Attributes attributes) {
			this.parentHandler = document;
			this.elementHandled = rootName;
			handleRootAttributes(attributes);
		}

		protected abstract void handleRootAttributes(Attributes attributes);

	}

	class DocHandler extends AbstractHandler {

		RootHandler rootHandler;

		public DocHandler(String rootName, RootHandler rootHandler) {
			super(null, rootName);
			this.rootHandler = rootHandler;
		}

		public void startElement(String name, Attributes attributes) {
			if (name.equals(elementHandled)) {
				rootHandler.initialize(this, name, attributes);
				xmlReader.setContentHandler(rootHandler);
			} else
				noSubElements(name, attributes);
		}

	}

	class EndpointDescriptionDocHandler extends DocHandler {

		public EndpointDescriptionDocHandler(String rootName,
				RootHandler rootHandler) {
			super(rootName, rootHandler);
		}

		public void processingInstruction(String target, String data)
				throws SAXException {
			// do nothing
		}
	}

	class EndpointDescriptionsHandler extends RootHandler {

		private List<EndpointDescription> endpointDescriptions = new ArrayList<EndpointDescription>();
		private EndpointDescriptionHandler endpointDescriptionHandler;

		protected void handleRootAttributes(Attributes attributes) {
		}

		public void startElement(String name, Attributes attributes)
				throws SAXException {
			if (ENDPOINT_DESCRIPTION.equals(name)) {
				if (endpointDescriptionHandler == null) {
					endpointDescriptionHandler = new EndpointDescriptionHandler(
							this, attributes, endpointDescriptions);
				} else
					duplicateElement(this, name, attributes);
			} else
				invalidElement(name, attributes);
		}

		public void endElement(String namespaceURI, String localName,
				String qName) {
			if (elementHandled.equals(localName)) {
				endpointDescriptionHandler = null;
				super.endElement(namespaceURI, localName, qName);
			}
		}

		public List<EndpointDescription> getEndpointDescriptions() {
			return endpointDescriptions;
		}
	}

	class EndpointDescriptionHandler extends AbstractHandler {

		private Map<String, Object> properties;
		private List<EndpointDescription> descriptions;

		public EndpointDescriptionHandler(ContentHandler parentHandler,
				Attributes attributes, List<EndpointDescription> descriptions) {
			super(parentHandler, ENDPOINT_DESCRIPTION);
			this.properties = new TreeMap<String, Object>(
					String.CASE_INSENSITIVE_ORDER);
			this.descriptions = descriptions;
		}

		public void startElement(String name, Attributes attributes)
				throws SAXException {
			if (ENDPOINT_PROPERTY.equals(name)) {
				new EndpointPropertyHandler(this, attributes, properties);
			}
		}

		public void endElement(String namespaceURI, String localName,
				String qName) {
			if (elementHandled.equals(localName)) {
				this.descriptions.add(new EndpointDescription(properties));
				super.endElement(namespaceURI, localName, qName);
			}
		}

	}

	private Object createValue(String valueType, String value) {
		if (value == null)
			return null;
		if (valueType.equals("String")) { //$NON-NLS-1$
			return value;
		} else if (valueType.equals("long") || valueType.equals("Long")) { //$NON-NLS-1$ //$NON-NLS-2$
			return Long.valueOf(value);
		} else if (valueType.equals("double") || valueType.equals("Double")) { //$NON-NLS-1$ //$NON-NLS-2$
			return Double.valueOf(value);
		} else if (valueType.equals("float") || valueType.equals("Float")) { //$NON-NLS-1$ //$NON-NLS-2$
			return Float.valueOf(value);
		} else if (valueType.equals("int") || valueType.equals("Integer")) { //$NON-NLS-1$ //$NON-NLS-2$
			return Integer.valueOf(value);
		} else if (valueType.equals("byte") || valueType.equals("Byte")) { //$NON-NLS-1$ //$NON-NLS-2$
			return Byte.valueOf(value);
		} else if (valueType.equals("char") //$NON-NLS-1$
				|| valueType.equals("Character")) { //$NON-NLS-1$
			char[] chars = new char[1];
			value.getChars(0, 1, chars, 0);
			return Character.valueOf(chars[0]);
		} else if (valueType.equals("boolean") //$NON-NLS-1$
				|| valueType.equals("Boolean")) { //$NON-NLS-1$
			return Boolean.valueOf(value);
		} else if (valueType.equals("short") || valueType.equals("Short")) { //$NON-NLS-1$ //$NON-NLS-2$
			return Short.valueOf(value);
		}
		return null;
	}

	abstract class MultiValueHandler extends AbstractHandler {

		protected String valueType;

		public MultiValueHandler(ContentHandler parentHandler,
				String elementHandled, String valueType) {
			super(parentHandler, elementHandled);
			this.valueType = valueType;
		}

		public void startElement(String name, Attributes attributes)
				throws SAXException {
			if (ENDPOINT_PROPERTY_VALUE.equals(name))
				characters = new StringBuffer();
		}

		public void endElement(String namespaceURI, String localName,
				String qName) {
			if (ENDPOINT_PROPERTY_VALUE.equals(localName)) {
				Object value = createValue(
						valueType,
						processValue((characters == null) ? null : characters
								.toString()));
				if (value != null)
					addValue(value);
				characters = null;
			} else if (elementHandled.equals(localName))
				super.endElement(namespaceURI, localName, qName);
		}

		private String processValue(String characters) {
			if (characters == null || characters.length() == 0)
				return null;
			if (valueType.equals("String")) //$NON-NLS-1$
				return characters;
			return characters.trim();
		}

		protected abstract void addValue(Object value);

		public abstract Object getValues();
	}

	class ArrayMultiValueHandler extends MultiValueHandler {

		private List<Object> values = new ArrayList<Object>();

		public ArrayMultiValueHandler(ContentHandler parentHandler,
				String elementHandled, String valueType) {
			super(parentHandler, elementHandled, valueType);
		}

		protected Object[] createEmptyArrayOfType() {
			if (valueType.equals("String")) //$NON-NLS-1$
				return new String[] {};
			else if (valueType.equals("long") || valueType.equals("Long")) //$NON-NLS-1$ //$NON-NLS-2$
				return new Long[] {};
			else if (valueType.equals("double") || valueType.equals("Double")) //$NON-NLS-1$ //$NON-NLS-2$
				return new Double[] {};
			else if (valueType.equals("float") || valueType.equals("Float")) //$NON-NLS-1$ //$NON-NLS-2$
				return new Double[] {};
			else if (valueType.equals("int") || valueType.equals("Integer")) //$NON-NLS-1$ //$NON-NLS-2$
				return new Integer[] {};
			else if (valueType.equals("byte") || valueType.equals("Byte")) //$NON-NLS-1$ //$NON-NLS-2$
				return new Byte[] {};
			else if (valueType.equals("char") //$NON-NLS-1$
					|| valueType.equals("Character")) //$NON-NLS-1$
				return new Character[] {};
			else if (valueType.equals("boolean") //$NON-NLS-1$
					|| valueType.equals("Boolean")) //$NON-NLS-1$
				return new Boolean[] {};
			else if (valueType.equals("short") || valueType.equals("Short")) //$NON-NLS-1$ //$NON-NLS-2$
				return new Short[] {};
			else
				return null;
		}

		public Object getValues() {
			return values.toArray(createEmptyArrayOfType());
		}

		protected void addValue(Object value) {
			values.add(value);
		}
	}

	class ListMultiValueHandler extends MultiValueHandler {

		private List<Object> values = new ArrayList<Object>();

		public ListMultiValueHandler(ContentHandler parentHandler,
				String elementHandled, String valueType) {
			super(parentHandler, elementHandled, valueType);
		}

		public Object getValues() {
			return values;
		}

		protected void addValue(Object value) {
			values.add(value);
		}
	}

	class SetMultiValueHandler extends MultiValueHandler {

		private Set<Object> values = new HashSet<Object>();

		public SetMultiValueHandler(ContentHandler parentHandler,
				String elementHandled, String valueType) {
			super(parentHandler, elementHandled, valueType);
		}

		public Object getValues() {
			return values;
		}

		protected void addValue(Object value) {
			values.add(value);
		}
	}

	class XMLValueHandler extends AbstractHandler {

		private Map<String, String> nsPrefixMap = new HashMap<String, String>();
		private StringBuffer buf;

		public XMLValueHandler(ContentHandler parentHandler) {
			super(parentHandler, ENDPOINT_PROPERTY_XML);
			buf = new StringBuffer();
		}

		public void startPrefixMapping(String prefix, String uri)
				throws SAXException {
			nsPrefixMap.put(uri, prefix);
		}

		public void startElement(String uri, String localName, String qName,
				Attributes attributes) throws SAXException {
			buf.append("<").append(qName); //$NON-NLS-1$
			for (Iterator<String> i = nsPrefixMap.keySet().iterator(); i
					.hasNext();) {
				String nsURI = (String) i.next();
				String prefix = (String) nsPrefixMap.get(nsURI);
				i.remove();
				if (nsURI != null) {
					buf.append(" xmlns"); //$NON-NLS-1$
					if (prefix != null)
						buf.append(":").append(prefix); //$NON-NLS-1$
					buf.append("=\"").append(nsURI).append("\""); //$NON-NLS-1$ //$NON-NLS-2$
				}
			}
			for (int i = 0; i < attributes.getLength(); i++) {
				buf.append(" "); //$NON-NLS-1$
				buf.append(attributes.getQName(i))
						.append("=\"").append(attributes.getValue(i)).append("\""); //$NON-NLS-1$ //$NON-NLS-2$
			}
			buf.append(">"); //$NON-NLS-1$
			characters = new StringBuffer();
		}

		public void startElement(String name, Attributes attributes)
				throws SAXException {
			// not used
		}

		public void endElement(String namespaceURI, String localName,
				String qName) {
			if (elementHandled.equals(localName)) {
				super.endElement(namespaceURI, localName, qName);
			} else {
				if (characters != null)
					buf.append(characters);
				buf.append("</").append(qName).append(">"); //$NON-NLS-1$ //$NON-NLS-2$
				characters = null;
			}
		}

		public String getXML() {
			return buf.toString();
		}
	}

	class EndpointPropertyHandler extends AbstractHandler {

		private Map<String, Object> properties;
		private String name;
		private String valueType = "String"; //$NON-NLS-1$
		private Object value;
		private MultiValueHandler multiValueHandler;
		private XMLValueHandler xmlValueHandler;

		public EndpointPropertyHandler(ContentHandler parentHandler,
				Attributes attributes, Map<String, Object> properties)
				throws SAXException {
			super(parentHandler, ENDPOINT_PROPERTY);
			name = parseRequiredAttributes(attributes,
					new String[] { ENDPOINT_PROPERTY_NAME })[0];
			String strValue = parseOptionalAttribute(attributes,
					ENDPOINT_PROPERTY_VALUE);
			String vt = parseOptionalAttribute(attributes,
					ENDPOINT_PROPERTY_VALUETYPE);
			if (vt != null) {
				if (!multiValueTypes.contains(vt))
					throw new SAXException("property element valueType=" + vt //$NON-NLS-1$
							+ " not allowed"); //$NON-NLS-1$
				this.valueType = vt;
			}
			this.properties = properties;
			if (strValue != null) {
				value = createValue(this.valueType, strValue);
				if (isValidProperty(name, value))
					this.properties.put(name, value);
			}
		}

		public void startElement(String name, Attributes attributes)
				throws SAXException {
			// Should not happen if value is non-null
			if (value != null)
				throw new SAXException(
						"property element has both value attribute and sub-element"); //$NON-NLS-1$
			if (ENDPOINT_PROPERTY_ARRAY.equals(name)) {
				if (multiValueHandler == null)
					multiValueHandler = new ArrayMultiValueHandler(this,
							ENDPOINT_PROPERTY_ARRAY, valueType);
				else
					duplicateElement(this, name, attributes);

			} else if (ENDPOINT_PROPERTY_LIST.equals(name)) {
				if (multiValueHandler == null)
					multiValueHandler = new ListMultiValueHandler(this,
							ENDPOINT_PROPERTY_LIST, valueType);
				else
					duplicateElement(this, name, attributes);
			} else if (ENDPOINT_PROPERTY_SET.equals(name)) {
				if (multiValueHandler == null)
					multiValueHandler = new SetMultiValueHandler(this,
							ENDPOINT_PROPERTY_SET, valueType);
				else
					duplicateElement(this, name, attributes);
			} else if (ENDPOINT_PROPERTY_XML.equals(name)) {
				// xml
				if (xmlValueHandler == null)
					xmlValueHandler = new XMLValueHandler(this);
				else
					duplicateElement(this, name, attributes);

			} else
				invalidElement(name, attributes);
		}

		public void endElement(String namespaceURI, String localName,
				String qName) {
			if (elementHandled.equals(localName)) {
				if (multiValueHandler != null) {
					properties.put(name, multiValueHandler.getValues());
					multiValueHandler = null;
				} else if (xmlValueHandler != null) {
					properties.put(name, xmlValueHandler.getXML());
					xmlValueHandler = null;
				}
				super.endElement(namespaceURI, localName, qName);
			}
		}

		private boolean isValidProperty(String name, Object value) {
			return (name != null && value != null);
		}
	}

	public class EndpointDescription {
		private Map<String, Object> properties;

		public EndpointDescription(Map<String, Object> properties) {
			this.properties = properties;
		}

		public Map<String, Object> getProperties() {
			return properties;
		}

		public String toString() {
			StringBuilder builder = new StringBuilder();
			builder.append("EndpointDescription [properties="); //$NON-NLS-1$
			builder.append(properties);
			builder.append("]"); //$NON-NLS-1$
			return builder.toString();
		}

	}

	public synchronized void parse(InputStream input) throws IOException {
		try {
			getParser();
			EndpointDescriptionsHandler endpointDescriptionsHandler = new EndpointDescriptionsHandler();
			xmlReader.setContentHandler(new EndpointDescriptionDocHandler(
					ENDPOINT_DESCRIPTIONS, endpointDescriptionsHandler));
			xmlReader.parse(new InputSource(input));
			endpointDescriptions = endpointDescriptionsHandler
					.getEndpointDescriptions();
		} catch (SAXException e) {
			throw new IOException(e.getMessage());
		} catch (ParserConfigurationException e) {
			throw new IOException(e.getMessage());
		} finally {
			input.close();
		}

	}

	public static String makeSimpleName(String localName, String qualifiedName) {
		if (localName != null && localName.length() > 0)
			return localName;
		int nameSpaceIndex = qualifiedName.indexOf(":"); //$NON-NLS-1$
		return (nameSpaceIndex == -1 ? qualifiedName : qualifiedName
				.substring(nameSpaceIndex + 1));
	}

	public void unexpectedElement(AbstractHandler handler, String element,
			Attributes attributes) {
	}

	public void unexpectedCharacterData(AbstractHandler handler, String cdata) {
	}

	public void unexpectedAttribute(String element, String attribute,
			String value) {
	}

	static int indexOf(String[] array, String value) {
		for (int i = 0; i < array.length; i += 1) {
			if (value == null ? array[i] == null : value.equals(array[i])) {
				return i;
			}
		}
		return -1;
	}

	public void checkRequiredAttribute(String element, String name, Object value) {
	}

	public void duplicateElement(AbstractHandler handler, String element,
			Attributes attributes) {
		// ignore the duplicate element entirely because we have already logged
		// it
		new IgnoringHandler(handler);
	}

	private List<EndpointDescription> endpointDescriptions;

	public List<EndpointDescription> getEndpointDescriptions() {
		return endpointDescriptions;
	}

}
