/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.dtd.core.internal.saxparser;

import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Stack;
import java.util.Vector;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolver;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverPlugin;
import org.eclipse.wst.common.uriresolver.internal.util.URIHelper;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.DeclHandler;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.DefaultHandler;

public class DTDParser extends DefaultHandler implements ContentHandler, DTDHandler, ErrorHandler, DeclHandler, LexicalHandler {
	private String contentString = ""; //$NON-NLS-1$
	private String declString = ""; //$NON-NLS-1$

	/* Canonical output. */
	protected boolean canonical;

	protected XMLReader reader;
	int entityDepth;

	// dmw 11/15 private field never read locally
	// private Vector declElements;
	private String comment = null;
	private ErrorMessage errorMessage = null;
	private List errorMessages = new ArrayList();
	private DeclNode previousDeclNode = null;
	private DeclNode currentDeclNode = null;
	private BaseNode lastBaseNode = null;

	private boolean entityEnd = false;
	private int lineNumber;

	private DTD currentDTD = null;
	private Vector dtdList = new Vector();

	private Stack dtdStack = new Stack();
	private Stack peRefStack = new Stack();
	private Stack parsingPERefStack = new Stack();

	private EntityPool entityPool = new EntityPool();
	private String expandedEntityValue = null;
	private Hashtable elementPool = new Hashtable();

	boolean parsingExternalPEReference = false;
	protected boolean expandEntityReferences = true;

	private Locator locator = null;

	private Locator getLocator() {
		return locator;
	}

	public void setDocumentLocator(Locator locator) {
		this.locator = locator;
	}

	public DTDParser(boolean canonical) throws UnsupportedEncodingException {
		this(null, canonical);
	}

	protected DTDParser(String encoding, boolean canonical) throws UnsupportedEncodingException {

		if (encoding == null)
			encoding = "UTF-8"; //$NON-NLS-1$

		this.canonical = canonical;
		try {
			SAXParser sparser = SAXParserFactory.newInstance().newSAXParser();
			reader = sparser.getXMLReader();
			reader.setProperty("http://xml.org/sax/properties/declaration-handler", this); //$NON-NLS-1$
			reader.setProperty("http://xml.org/sax/properties/lexical-handler", this); //$NON-NLS-1$
			reader.setContentHandler(this);
			reader.setDTDHandler(this);
			reader.setErrorHandler(this);
			reader.setEntityResolver(this);
		}
		catch (Exception e) {
			e.printStackTrace();
		}

	}

	/* Prints the output from the SAX callbacks. */
	public void parse(String uri) {
		try {
			boolean isReadable = URIHelper.isReadableURI(uri, true);
			if (!isReadable) {
				throw new Exception("DTD parse error. Can not read the specified URI : " + uri); //$NON-NLS-1$
			}

			String document = "<!DOCTYPE root SYSTEM \"" + uri + "\"><root/>"; //$NON-NLS-1$ //$NON-NLS-2$
			entityDepth = 0;
			currentDTD = new DTD(uri);
			InputSource inputSource = new InputSource(new StringReader(document));
			inputSource.setSystemId(uri + ".xml"); //$NON-NLS-1$
			reader.parse(inputSource);
		}
		catch (SAXParseException se) {
			if (currentDTD != null)
				currentDTD.setIsExceptionDuringParse(true);
		}
		catch (Exception e) {
			if (currentDTD != null)
				currentDTD.setIsExceptionDuringParse(true);
		}

	}

	/*
	 * @deprecated Entity references are always expanded.
	 */
	public void setExpandEntityReferences(boolean expandEntityReferences) {
		this.expandEntityReferences = true;
	}

	/*
	 * @deprecated Entity references are always expanded.
	 */
	public boolean getExpandEntityReferences() {
		return expandEntityReferences;
	}

	public Vector getDTDList() {
		return dtdList;
	}

	public Hashtable getElementPool() {
		return elementPool;
	}

	public EntityPool getEntityPool() {
		return entityPool;
	}

	public List getErrorMessages() {
		return errorMessages;
	}

	//
	// DocumentHandler methods
	//

	public void startDocument() {
	}

	public void endDocument() {
	}

	public void processingInstruction(String target, String data) {
	}

	//
	// DTDHandler methods
	//

	public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) throws SAXException {
	}

	public void notationDecl(String name, String publicId, String systemId) throws SAXException {
		startDeclaration(DeclNode.NOTATION);
		declString = "<!NOTATION"; //$NON-NLS-1$
		if (entityDepth == 1 || parsingExternalPEReference) {
			String xs = " "; //$NON-NLS-1$
			xs += name;
			if (publicId == null)
				xs += " SYSTEM " + "\"" + systemId + "\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			else
				xs += " PUBLIC " + "\"" + publicId + "\" " + "\"" + systemId + "\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
			contentString += xs;
			parseCurrentDeclaration();
		}
	}

	//
	// DeclHandler methods
	//

	public void elementDecl(String name, String model) throws SAXException {
		startDeclaration(DeclNode.ELEMENT);
		declString = "<!ELEMENT"; //$NON-NLS-1$

		// KB: With early versions of Xerces 2.x, startEntity("[dtd]") used to
		// be called before this method
		// so entityDepth was 1. Using JAXP changed that and startEntity() is
		// not called back anymore.
		// Because of this, we need to handle the case where entityDepth == 0
		// as well.
		if (entityDepth == 0 || entityDepth == 1 || parsingExternalPEReference)
			parseCurrentDeclarationHelper(name + " " + model); //$NON-NLS-1$
	}

	protected String attributeString = ""; //$NON-NLS-1$

	public void attributeDecl(String eName, String aName, String type, String valueDefault, String value) throws SAXException {
		startDeclaration(DeclNode.ATTLIST);
		declString = "<!ATTLIST"; //$NON-NLS-1$

		attributeString += " " + aName; //$NON-NLS-1$
		if (type != null)
			attributeString += " " + type; //$NON-NLS-1$
		if (valueDefault != null)
			attributeString += " " + valueDefault; //$NON-NLS-1$
		if (value != null)
			attributeString += " '" + value + "'"; //$NON-NLS-1$ //$NON-NLS-2$

		attributeString = eName + " " + attributeString + ">"; //$NON-NLS-1$ //$NON-NLS-2$
		parseCurrentDeclarationHelper(attributeString);
		attributeString = ""; //$NON-NLS-1$
	}

	public void internalEntityDecl(String name, String value) throws SAXException {
		startDeclaration(DeclNode.INTERNAL_ENTITY);
		declString = "<!ENTITY"; //$NON-NLS-1$

		if (entityDepth == 1 || parsingExternalPEReference) {
			// build up a string: e.g. " % STRDOM "(#PCDATA)">"
			String xs = " "; //$NON-NLS-1$
			if (name.startsWith("%")) { //$NON-NLS-1$
				xs += "% "; //$NON-NLS-1$
				xs += name.substring(1);
			}
			else
				xs += name;

			xs += " \"" + value + "\">"; //$NON-NLS-1$ //$NON-NLS-2$

			contentString += xs;
			// save expanded entity value
			expandedEntityValue = value;
			parseCurrentDeclaration();

		}
	}

	public void externalEntityDecl(String name, String publicId, String systemId) throws SAXException {
		startDeclaration(DeclNode.EXTERNAL_ENTITY);
		declString = "<!ENTITY"; //$NON-NLS-1$

		if (entityDepth == 1 || parsingExternalPEReference) {
			// build up a string:
			// ex1) " % FIELD SYSTEM "oagis_fields.dtd">"
			// ex2) " % FIELD PUBLIC "FOO">"
			String xs = " "; //$NON-NLS-1$
			if (name.startsWith("%")) { //$NON-NLS-1$
				xs += "% "; //$NON-NLS-1$
				xs += name.substring(1);
			}
			else
				xs += name;

			if (systemId != null)
				xs += " SYSTEM \"" + systemId + "\">"; //$NON-NLS-1$ //$NON-NLS-2$
			else if (publicId != null)
				xs += " PUBLIC \"" + publicId + "\">"; //$NON-NLS-1$ //$NON-NLS-2$

			contentString += xs;
			parseCurrentDeclaration();
		}
	}

	//
	// LexicalHandler methods
	//

	public void startCDATA() throws SAXException {
	}

	public void endCDATA() throws SAXException {
	}

	public void startDTD(String name, String publicId, String systemId) throws SAXException {
		dtdList.removeAllElements();
		dtdList.addElement(currentDTD);
	}

	/**
	 * Report the end of DTD declarations.
	 * 
	 * @exception SAXException
	 *                The application may raise an exception.
	 * @see #startDTD
	 */
	public void endDTD() throws SAXException {
		startDeclaration(DeclNode.END_DTD);
	}

	/**
	 * Report the beginning of an entity.
	 * 
	 * The start and end of the document entity are not reported. The start
	 * and end of the external DTD subset are reported using the pseudo-name
	 * "[dtd]". All other events must be properly nested within start/end
	 * entity events.
	 * 
	 * @param name
	 *            The name of the entity. If it is a parameter entity, the
	 *            name will begin with '%'.
	 * @exception SAXException
	 *                The application may raise an exception.
	 * @see #endEntity
	 */

	public void startEntity(String name) throws SAXException {
		if (name.equals("[dtd]")) { //$NON-NLS-1$
			startDeclaration(DeclNode.START_ENTITY_DTD);
		}
		else if (currentDeclNode == null) {
			// PE reference in markupdecl section
			if (name.startsWith("%")) { //$NON-NLS-1$
				String peName = name.substring(1);
				EntityDecl en = entityPool.referPara(peName);

				peRefStack.push(name);
				parsingPERefStack.push(new Boolean(parsingExternalPEReference));

				String systemId = en.getSystemId();
				String publicId = en.getPublicId();
				if (systemId == null) {
					parsingExternalPEReference = false;
				}
				else {
					URIResolver idResolver = URIResolverPlugin.createResolver();
					String uri = idResolver.resolve(currentDTD.getName(), publicId, systemId);
					if (!isDTDLoaded(uri)) {
						// not loaded
						// out.println(" DTD not loaded .. create new DTD: "
						// );
						dtdStack.push(currentDTD);
						DTD newDTD = new DTD(uri);
						dtdList.addElement(newDTD);
						currentDTD = newDTD;
						parsingExternalPEReference = true;
					}
					else {
						// out.println(" DTD already loaded .. " );
						parsingExternalPEReference = false;
					}
				}
			}
		}
		else if (entityDepth == 1 || parsingExternalPEReference) {
			String xs = (String) reader.getProperty("http://xml.org/sax/properties/xml-string"); //$NON-NLS-1$
			contentString += xs;
		}
		entityDepth++;
	}

	/**
	 * Report the end of an entity.
	 * 
	 * @param name
	 *            The name of the entity that is ending.
	 * @exception SAXException
	 *                The application may raise an exception.
	 * @see #startEntity
	 */
	public void endEntity(String name) throws SAXException {
		if (name.equals("[dtd]")) { //$NON-NLS-1$
			startDeclaration(DeclNode.END_ENTITY_DTD);
		}
		else if (!peRefStack.empty()) {
			parseExternalPEReference(name);
		}
		else if (entityDepth == 1 || parsingExternalPEReference) {
			if (!contentString.endsWith(name + ";")) { //$NON-NLS-1$
				String xs = (String) reader.getProperty("http://xml.org/sax/properties/xml-string"); //$NON-NLS-1$
				contentString += xs;
			}
		}
		entityDepth--;
		entityEnd = true;
	}

	protected boolean parseExternalPEReference(String name) {
		if (!peRefStack.empty()) {
			if (((String) peRefStack.peek()).equals(name)) {
				peRefStack.pop();
				if (parsingExternalPEReference) {
					currentDTD = (DTD) dtdStack.pop();
					addPEReferenceNode(name);
				}
				parsingExternalPEReference = ((Boolean) parsingPERefStack.pop()).booleanValue();
				return true;
			}
		}
		return false;
	}

	/**
	 * Report an XML comment anywhere in the document.
	 * 
	 * This callback will be used for comments inside or outside the document
	 * element, including comments in the external DTD subset (if read).
	 * 
	 * @param ch
	 *            An array holding the characters in the comment.
	 * @param start
	 *            The starting position in the array.
	 * @param length
	 *            The number of characters to use from the array.
	 * @exception SAXException
	 *                The application may raise an exception.
	 */
	public void comment(char ch[], int start, int length) throws SAXException {
		startDeclaration(DeclNode.COMMENT);

		if (comment == null)
			comment = new String(ch);
		else
			comment += "\n" + new String(ch); // append all comments. //$NON-NLS-1$
		// The comment will get reset after
		// it has been attached to the following
		// declaration.
	}

	//
	// ErrorHandler methods
	//

	/* Warning. */
	public void warning(SAXParseException ex) {
		String error = "[Source Line] " + declString + contentString + "\n";  //$NON-NLS-1$//$NON-NLS-2$
		error += "[Warning    ] " + getLocationString(ex) + ": " + ex.getMessage();  //$NON-NLS-1$//$NON-NLS-2$
		setErrorInformation(ex, "warning"); //$NON-NLS-1$

		parseCurrentDeclaration();
	}

	/* Error. */
	public void error(SAXParseException ex) {
		String error = "[Source Line] " + declString + contentString + "\n";  //$NON-NLS-1$//$NON-NLS-2$
		error += "[Error   ] " + getLocationString(ex) + ": " + ex.getMessage();  //$NON-NLS-1$//$NON-NLS-2$
		setErrorInformation(ex, "error"); //$NON-NLS-1$

		parseCurrentDeclaration();
	}

	/* Fatal error. */
	public void fatalError(SAXParseException ex) throws SAXException {
		String error = "[Source Line] " + declString + contentString + "\n";  //$NON-NLS-1$//$NON-NLS-2$
		error += "[Fatal Error] " + getLocationString(ex) + ": " + ex.getMessage();  //$NON-NLS-1$//$NON-NLS-2$
		setErrorInformation(ex, "fatal"); //$NON-NLS-1$

		parseCurrentDeclaration();
	}

	/* Returns a string of the location. */
	private String getLocationString(SAXParseException ex) {
		StringBuffer str = new StringBuffer();

		String systemId = ex.getSystemId();
		if (systemId != null) {
			int index = systemId.lastIndexOf('/');
			if (index != -1)
				systemId = systemId.substring(index + 1);
			str.append(systemId);
		}
		str.append(':');
		str.append(ex.getLineNumber());
		str.append(':');
		str.append(ex.getColumnNumber());

		return str.toString();

	}

	private void startDeclaration(int type) {
		if (type == DeclNode.END_DTD || type == DeclNode.END_ENTITY_DTD || type == DeclNode.COMMENT || type == DeclNode.ERROR) {
			previousDeclNode = currentDeclNode;
			currentDeclNode = null;
		}
		else {
			currentDeclNode = new DeclNode(type);
			contentString = ""; //$NON-NLS-1$
			declString = ""; //$NON-NLS-1$
			expandedEntityValue = null;
		}
	}

	private void parseCurrentDeclaration() {
		parseCurrentDeclarationHelper(contentString);
		contentString = ""; //$NON-NLS-1$
	}

	private void parseCurrentDeclarationHelper(String declarationString) {
		DTDScanner scanner;
		String name;

		if (currentDeclNode == null && previousDeclNode != null && entityEnd) {
			currentDeclNode = previousDeclNode;
		}

		// save the previous declNode
		if (currentDeclNode != null) {
			BaseNode baseNode = null;
			// strip out the ending markup symbol ">"
			if (declarationString.endsWith(">")) //$NON-NLS-1$
				declarationString = declarationString.substring(0, declarationString.length() - 1);

			int sIndex;
			String cString;
			int type = currentDeclNode.getType();
			switch (type) {
				case DeclNode.ELEMENT : {
					name = TString.word(declarationString, 1);

					// strip out the name
					sIndex = declarationString.indexOf(name) + name.length();
					cString = declarationString.substring(sIndex);

					baseNode = new ElementDecl(name, currentDTD.getName());
					scanner = new DTDScanner(currentDTD.getName(), cString);
					CMNode contentModel = scanner.scanContentModel();
					if (contentModel == null && errorMessage == null) {
						createErrorMessage("Expecting '(' in content model", "error"); //$NON-NLS-1$ //$NON-NLS-2$
					}

					((ElementDecl) baseNode).setContentModelNode(contentModel);
					elementPool.put(name, baseNode);
					break;
				}
				case DeclNode.INTERNAL_ENTITY :
				case DeclNode.EXTERNAL_ENTITY : {
					if (!parseExternalPEReference(declarationString)) {
						scanner = new DTDScanner(currentDTD.getName(), declarationString);
						baseNode = scanner.scanEntityDecl();
						// System.out.println("----baseNode (" +
						// declarationString + ")" + baseNode);
						if (type == DeclNode.INTERNAL_ENTITY && expandedEntityValue != null) {
							((EntityDecl) baseNode).expandedValue = expandedEntityValue;
						}
						if (baseNode != null) {
							entityPool.add((EntityDecl) baseNode);
						}
					}

					break;
				}
				case DeclNode.NOTATION : {
					scanner = new DTDScanner(currentDTD.getName(), declarationString);
					baseNode = scanner.scanNotationDecl();
					break;
				}
				case DeclNode.ATTLIST : {
					name = TString.word(declarationString, 1);

					// strip out the name
					sIndex = declarationString.indexOf(name) + name.length();
					cString = declarationString.substring(sIndex);

					baseNode = new Attlist(name, currentDTD.getName());
					scanner = new DTDScanner(currentDTD.getName(), cString.trim());
					Vector attrs = scanner.scanAttlistDecl(entityPool);
					String errorString = scanner.getErrorString();

					if (attrs.size() > 0) {
						((Attlist) baseNode).setAttDefs(attrs);
					}
					if (errorString != null) {
						createErrorMessage(errorString, "error"); //$NON-NLS-1$
					}
					break;
				}
				default : {
					currentDeclNode = null;
				}
			}

			if (baseNode != null) {
				if (comment != null) {
					baseNode.setComment(comment);
					comment = null;
				}

				if (errorMessage != null) {
					baseNode.setErrorMessage(errorMessage);
					errorMessage = null;
				}

				if (currentDeclNode != null) {
					currentDTD.addDecl(baseNode);
				}
				lastBaseNode = baseNode;
			}

			currentDeclNode = null;
		}
		else {
			if (lastBaseNode != null && errorMessage != null && lastBaseNode.getErrorMessage() == null) {
				lastBaseNode.setErrorMessage(errorMessage);
				errorMessage = null;
			}
		}
	}

	private void addPEReferenceNode(String name) {
		if (name.startsWith("%")) { //$NON-NLS-1$
			name = name.substring(1); // strip out the % from entity name
		}
		EntityDecl e = new EntityDecl(name, currentDTD.getName(), null, true);
		e.setEntityReferenced(true);
		e.setErrorMessage(errorMessage);
		errorMessage = null;
		currentDTD.addDecl(e);
	}

	private boolean isDTDLoaded(String uri) {
		boolean loaded = false;
		String list = ""; //$NON-NLS-1$
		if (dtdList != null) {
			Enumeration en = dtdList.elements();
			while (en.hasMoreElements()) {
				DTD dtd = (DTD) en.nextElement();
				list += dtd.getName();
				list += ","; //$NON-NLS-1$
				if (dtd.getName().equals(uri)) {
					loaded = true;
					break;
				}
			}
		}
		return loaded;
	}

	public InputSource resolveEntity(String publicId, String systemId) throws SAXException {
		InputSource result = null;
		URIResolver idResolver = URIResolverPlugin.createResolver();
		String uri = idResolver.resolve(currentDTD.getName(), publicId, systemId);
		if(uri == null){
			uri = systemId;
		}
		result = new InputSource(uri);
		return result;
	}

	//
	// Main
	//

	/** Main program entry point. */
	public static void main(String argv[]) {

		// is there anything to do?
		if (argv.length == 0) {
			printUsage();
			System.exit(1);
		}

		// vars
		boolean canonical = false;
		boolean expandEntityReferences = false;
		DTDParser parser;

		// check parameters
		for (int i = 0; i < argv.length; i++) {
			String arg = argv[i];

			// options
			if (arg.startsWith("-")) { //$NON-NLS-1$

				if (arg.equals("-c")) { //$NON-NLS-1$
					canonical = true;
					continue;
				}

				if (arg.equals("-x")) { //$NON-NLS-1$
					expandEntityReferences = true;
					continue;
				}

				if (arg.equals("-h")) { //$NON-NLS-1$
					printUsage();
					System.exit(1);
				}
			}
			try {
				parser = new DTDParser(canonical);
				parser.setExpandEntityReferences(expandEntityReferences);
				parser.parse(arg);
			}
			catch (Exception e) {
				e.printStackTrace();
			}
		}

	} // main(String[])

	/** Prints the usage. */
	private static void printUsage() {

		System.err.println("usage: java sax.DTDParser (options) uri ..."); //$NON-NLS-1$
		System.err.println();
		System.err.println("options:"); //$NON-NLS-1$
		System.err.println("  -c       Canonical XML output."); //$NON-NLS-1$
		System.err.println("  -x       Expand entity references."); //$NON-NLS-1$
		System.err.println("  -h       This help screen."); //$NON-NLS-1$

	} // printUsage()

	private void setErrorInformation(SAXParseException ex, String severity) {
		errorMessage = new ErrorMessage();

		if (ex.getLineNumber() == -1) {
			errorMessage.setErrorLine(lineNumber);
		}
		else {
			errorMessage.setErrorLine(ex.getLineNumber());
		}


		errorMessage.setErrorMessage(ex.getMessage());
		errorMessage.setErrorColumn(ex.getColumnNumber());
		errorMessage.setSeverity(severity);
		errorMessages.add(errorMessage);
	}

	private void createErrorMessage(String message, String severity) {
		errorMessage = new ErrorMessage();

		Locator locator = getLocator();

		errorMessage.setErrorLine(locator.getLineNumber());
		errorMessage.setErrorColumn(locator.getColumnNumber());

		errorMessage.setErrorMessage(message);
		errorMessage.setSeverity(severity);

		errorMessages.add(errorMessage);
	}

}
