/*******************************************************************************
 * Copyright (c) 2002, 2013 Object Factory Inc.
 *
 * This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *		Object Factory Inc. - Initial implementation
 *      IBM Corporation - Fix for bug 40951
 *******************************************************************************/
package org.eclipse.ant.internal.ui.dtd.schema;

import java.util.HashSet;
import java.util.LinkedList;

import org.eclipse.ant.internal.ui.dtd.IModel;
import org.eclipse.ant.internal.ui.dtd.ISchema;
import org.xml.sax.SAXException;
import org.xml.sax.ext.DeclHandler;

import com.ibm.icu.text.MessageFormat;

/**
 * SchemaFactory is a SAX DeclHandler that converts DTD ELEMENT and ATTLIST declarations to schema form on the fly. The only two methods available to
 * external users of SchemaFactory are its constructor and <code>getSchema()</code>. The latter returns the schema built by this process and should
 * not be called until the XML parser to which this handler is attached has finished parsing.
 * 
 * @author Bob Foster
 */
public class SchemaFactory implements DeclHandler {
	// used for parsing models
	private char[] fBuf;
	private int fLen;
	private int fPos;
	private Element fElement;

	private Schema fSchema;
	private static HashSet<String> fTypes = new HashSet<>();
	private Exception fErrorException;
	static {
		fTypes.add("CDATA"); //$NON-NLS-1$
		fTypes.add("ID"); //$NON-NLS-1$
		fTypes.add("IDREF"); //$NON-NLS-1$
		fTypes.add("IDREFS"); //$NON-NLS-1$
		fTypes.add("NMTOKEN"); //$NON-NLS-1$
		fTypes.add("NMTOKENS"); //$NON-NLS-1$
		fTypes.add("ENTITY"); //$NON-NLS-1$
		fTypes.add("ENTITIES"); //$NON-NLS-1$
	}

	/**
	 * Constructor.
	 */
	public SchemaFactory() {
		fSchema = new Schema();
	}

	/**
	 * @return ISchema produced from the DeclHandler. The schema is always correct, though it may be incomplete if the parse was interrupted due to
	 *         validation or well-formed errors.
	 */
	public ISchema getSchema() {
		fSchema.setErrorException(fErrorException);
		return fSchema;
	}

	/**
	 * @see org.xml.sax.ext.DeclHandler#attributeDecl(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
	 */
	@Override
	public void attributeDecl(String eName, String aName, String type, String valueDefault, String value) {
		Element element = getElement(eName);
		Attribute attr = (Attribute) element.getAttributes().get(aName);
		if (attr == null) {
			attr = new Attribute(aName, element);
			element.addAttribute(attr);

			String[] enumeration = null;
			if (fTypes.contains(type))
				attr.setType(type);
			else if (type.startsWith("NOTATION")) //$NON-NLS-1$
				enumeration = parseValues(type.substring("NOTATION".length() + 1), ','); //$NON-NLS-1$
			else {
				type = stripSurroundingParentheses(type);
				enumeration = parseValues(type, '|');
			}
			attr.setEnum(enumeration);

			attr.setRequired(valueDefault == null || !valueDefault.equals("#IMPLIED")); //$NON-NLS-1$
			attr.setFixed(valueDefault != null && valueDefault.equals("#FIXED")); //$NON-NLS-1$
			attr.setDefault(value);
		}
	}

	/**
	 * Strips the surrounding parentheses from <code>aString</code>.
	 * <P>
	 * i.e.: (true|false) -> true|false
	 */
	private String stripSurroundingParentheses(String aString) {
		if (aString.startsWith("(")) { //$NON-NLS-1$
			aString = aString.substring(1);
		}
		if (aString.endsWith(")")) { //$NON-NLS-1$
			aString = aString.substring(0, aString.length() - 1);
		}
		return aString;
	}

	/**
	 * @param eName
	 *            Element name
	 * @return Element from schema or new element. Either way the element is in the schema upon return.
	 */
	private Element getElement(String eName) {
		Element element = (Element) fSchema.getElement(eName);
		if (element == null) {
			element = new Element(eName);
			fSchema.addElement(element);
		}
		return element;
	}

	private String[] parseValues(String type, char separator) {
		int start = 0, pos, len = type.length();
		LinkedList<String> values = new LinkedList<>();
		while (start < len) {
			pos = type.indexOf(separator, start);
			if (pos < 0)
				pos = len;
			String term = type.substring(start, pos);
			start = pos + 1;
			values.add(term);
		}
		return values.toArray(new String[values.size()]);
	}

	/**
	 * @see org.xml.sax.ext.DeclHandler#elementDecl(java.lang.String, java.lang.String)
	 */
	@Override
	public void elementDecl(String name, String model) throws SAXException {
		Element element = getElement(name);
		if (!element.isUndefined()) {
			// if the element has already been defined, this is an error
			throw new SAXException(MessageFormat.format(AntDTDSchemaMessages.SchemaFactory_Doubly_defined, new Object[] { name }));
		}

		fElement = element;
		if (model.equals("ANY")) { //$NON-NLS-1$
			element.setAny(true);
		} else if (model.equals("EMPTY")) { //$NON-NLS-1$
			element.setEmpty(true);
		} else if (model.equals("(#PCDATA)")) {//$NON-NLS-1$
			element.setText(true);
		} else {
			element.setContentModel(parseModel(model));
		}
	}

	/**
	 * Convert model string to IModel. The <code>fElement</code> variable is an implicit argument to this method, and it sets <code>fBuf</code>,
	 * <code>fPos</code> and <code>fLen</code> for use by other parser methods.
	 * 
	 * @param model
	 *            String from DTD, with parameter entities replaced.
	 * @return IModel
	 * @throws SAXException
	 *             if syntax error detected in model. This is a validation error. Since the DTD is usually not read unless the parser is validating,
	 *             we may not ever be handed a bad content model, but we need to check them, just the same.
	 */
	private IModel parseModel(String model) throws SAXException {
		fBuf = model.toCharArray();
		fLen = fBuf.length;
		if (fBuf[0] != '(') {
			throw new SAXException(MessageFormat.format(AntDTDSchemaMessages.SchemaFactory_Start_with_left_parenthesis, new Object[] { fElement.getName() }));
		}

		boolean ortext = model.startsWith("(#PCDATA|"); //$NON-NLS-1$
		if (ortext) {
			fPos = 8; // "(#PCDATA".length()
		} else {
			fPos = 0;
		}
		IModel emodel = scanExpr();
		return emodel;
	}

	/**
	 * Scan a parenthesized expression starting from the left parenthesis or leftmost operator.
	 * 
	 * @return IModel
	 */
	private IModel scanExpr() throws SAXException {
		// skip opening ( or |
		fPos++;
		return scanExpr(scanElement());
	}

	/**
	 * Scan a parenthesized expression with the first term in hand.
	 * 
	 * @param term
	 *            The first operand in the expression, pre-scanned.
	 * @return IModel
	 * @throws SAXException
	 *             if errors are detected in the model.
	 */
	private IModel scanExpr(IModel term) throws SAXException {
		checkLen();
		if (fBuf[fPos] != ')') {
			char op = fBuf[fPos];
			if (op != '|' && op != ',') {
				throw new SAXException(MessageFormat.format(AntDTDSchemaMessages.SchemaFactory_Expecting_operator_or_right_parenthesis, new Object[] {
						fElement.getName(), String.valueOf(fBuf) }));
			}
			Model model = new Model(op == '|' ? IModel.CHOICE : IModel.SEQUENCE);
			model.addModel(term);
			term = model;

			while (fBuf[fPos] == op) {
				fPos++;
				IModel next = scanElement();
				model.addModel(next);
			}
			if (fBuf[fPos] != ')') {
				throw new SAXException(MessageFormat.format(AntDTDSchemaMessages.SchemaFactory_Expecting_operator_or_right_parenthesis, new Object[] {
						fElement.getName(), String.valueOf(fBuf) }));
			}
			fPos++;
		}
		return term;
	}

	/**
	 * Scan an element name or a parenthesized sub-expression.
	 * 
	 * @return IModel
	 * @throws SAXException
	 */
	private IModel scanElement() throws SAXException {
		checkLen();
		if (fBuf[fPos] == '(')
			return scanExpr();
		StringBuffer sb = new StringBuffer();
		while (fBuf[fPos] != '|' && fBuf[fPos] != ',' && fBuf[fPos] != ')' && fBuf[fPos] != '*' && fBuf[fPos] != '+' && fBuf[fPos] != '?') {
			sb.append(fBuf[fPos++]);
			checkLen();
		}
		String name = sb.toString();
		Element element = getElement(name);
		Model model = new Model(IModel.LEAF);
		model.setLeaf(element);
		return model;
	}

	private void checkLen() throws SAXException {
		if (fPos == fLen) {
			throw new SAXException(MessageFormat.format(AntDTDSchemaMessages.SchemaFactory_Unexpected_end, new Object[] { fElement.getName(),
					String.valueOf(fBuf) }));
		}
	}

	/**
	 * @see org.xml.sax.ext.DeclHandler#externalEntityDecl(java.lang.String, java.lang.String, java.lang.String)
	 */
	@Override
	public void externalEntityDecl(String name, String publicId, String systemId) {
		// do nothing
	}

	/**
	 * @see org.xml.sax.ext.DeclHandler#internalEntityDecl(java.lang.String, java.lang.String)
	 */
	@Override
	public void internalEntityDecl(String name, String value) {
		// do nothing
	}

	public void setErrorException(Exception e) {
		fErrorException = e;
	}
}
