/*******************************************************************************
 * Copyright (c) 2005, 2008 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.xml.ui.internal.validation;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.validation.internal.core.IMessageAccess;
import org.eclipse.wst.validation.internal.core.ValidationException;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IProjectValidationContext;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
import org.eclipse.wst.validation.internal.provisional.core.IValidationContext;
import org.eclipse.wst.validation.internal.provisional.core.IValidator;
import org.eclipse.wst.validation.internal.provisional.core.IValidatorJob;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * A DelegatingReconcileValidator calls its delegate validator to get a list
 * of validation error IMessages. Using information in this IMessage the
 * DelegatingReconcileValidator updates the IMessage with an offset and length
 * to give a good range to be "squiggled" and adds the messages to the
 * IReporter
 * 
 * @author Mark Hutchinson
 * 
 */
public abstract class DelegatingSourceValidator implements IValidator {
	// the selection strategies:
	protected static final String ALL_ATTRIBUTES = "ALL_ATTRIBUTES"; //$NON-NLS-1$
	protected static final String ATTRIBUTE_NAME = "ATTRIBUTE_NAME"; //$NON-NLS-1$
	protected static final String ATTRIBUTE_VALUE = "ATTRIBUTE_VALUE"; //$NON-NLS-1$
	protected static final String START_TAG = "START_TAG"; //$NON-NLS-1$
	protected static final String TEXT = "TEXT"; //$NON-NLS-1$
	protected static final String FIRST_NON_WHITESPACE_TEXT = "FIRST_NON_WHITESPACE_TEXT"; //$NON-NLS-1$
	protected static final String TEXT_ENTITY_REFERENCE = "TEXT_ENTITY_REFERENCE"; //$NON-NLS-1$
	protected static final String VALUE_OF_ATTRIBUTE_WITH_GIVEN_VALUE = "VALUE_OF_ATTRIBUTE_WITH_GIVEN_VALUE"; //$NON-NLS-1$
	protected static final String END_TAG = "END_TAG"; //$NON-NLS-1$

	/**
	 * This constant specifies the attribute name that specifies the side of
	 * the 'start tag' that the validator has used to report an error. A
	 * validator may choose to report a message at the left (the start of the
	 * start tag)or at the right (the end of the start tag). When this
	 * attribute is not specified error ERROR_SIDE_LEFT is the default.
	 */
	protected static final String ERROR_SIDE = "ERROR_SIDE"; //$NON-NLS-1$

	/**
	 * When the ERROR_SIDE attribute specifies the ERROR_SIDE_LEFT value it is
	 * assumed that the message specifies a location to the left of the start
	 * tag
	 */
	protected static final String ERROR_SIDE_LEFT = "ERROR_SIDE_LEFT"; //$NON-NLS-1$	

	/**
	 * When the ERROR_SIDE attribute specifies the ERROR_SIDE_RIGHT value it
	 * is assumed that the message specifies a location to the right of the
	 * start tag
	 */
	protected static final String ERROR_SIDE_RIGHT = "ERROR_SIDE_RIGHT"; //$NON-NLS-1$	

	protected static final String COLUMN_NUMBER_ATTRIBUTE = "columnNumber"; //$NON-NLS-1$
	protected static final String SQUIGGLE_SELECTION_STRATEGY_ATTRIBUTE = "squiggleSelectionStrategy"; //$NON-NLS-1$
	protected static final String SQUIGGLE_NAME_OR_VALUE_ATTRIBUTE = "squiggleNameOrValue"; //$NON-NLS-1$

	public DelegatingSourceValidator() {
		super(); // constructor
	}

	public void cleanup(IReporter arg0) { // don't need to implement
	}

	// My Implementation of IHelper
	class MyHelper implements IProjectValidationContext {
		InputStream inputStream;

		IFile file;

		public MyHelper(InputStream inputStream, IFile file) {
			this.inputStream = inputStream;
			this.file = file;
		}

		public int getBuildKind() {
			return 0;
		}

		public Object loadModel(String symbolicName, Object[] parms) {
			if (symbolicName.equals("getFile")) { //$NON-NLS-1$
				return file;
			}
			return null;
		}

		public Object loadModel(String symbolicName) {
			if (symbolicName.equals("inputStream")) { //$NON-NLS-1$
				return inputStream;
			}
			return null;
		}

		public String[] getURIs() {
			if (file != null) {
				return new String[]{file.getFullPath().toString()};
			}
			return new String[0];
		}

		public IProject getProject() {
			if (file != null) {
				return file.getProject();
			}
			return null;
		}
	}

	// My Implementation of IReporter
	class MyReporter implements IReporter {
		List list = new ArrayList();

		public MyReporter() {
			super();
		}

		public void addMessage(IValidator origin, IMessage message) {
			list.add(message);
		}

		public void displaySubtask(IValidator validator, IMessage message) {
			/* do not need to implement */
		}

		public IMessageAccess getMessageAccess() {
			return null;
		}

		public boolean isCancelled() {
			return false;
		}

		public void removeAllMessages(IValidator origin, Object object) { // do
			/* do not need to implement */
		}

		public void removeAllMessages(IValidator origin) {
			/* do not need to implement */
		}

		public void removeMessageSubset(IValidator validator, Object obj, String groupName) {// do
			/* do not need to implement */
		}

		public List getMessages() {
			return list;
		}
	}

	protected abstract IValidator getDelegateValidator();

	/**
	 * Calls a delegate validator getting and updates it's list of
	 * ValidationMessages with a good squiggle offset and length.
	 * 
	 * @param helper
	 *            loads an object.
	 * @param reporter
	 *            Is an instance of an IReporter interface, which is used for
	 *            interaction with the user.
	 */
	public void validate(IValidationContext helper, IReporter reporter) throws ValidationException {
		String[] delta = helper.getURIs();
		if (delta.length > 0) {
			// get the file, model and document:
			IFile file = getFile(delta[0]);
			IDOMModel xmlModel = getModelForResource(file);
			try {
				IDOMDocument document = xmlModel.getDocument();

				// store the text in a byte array; make a full copy to ease
				// any threading problems
				byte[] byteArray;
				try {
					byteArray = xmlModel.getStructuredDocument().get().getBytes("UTF-8");
				}
				catch (UnsupportedEncodingException e) {
					// Not likely to happen
					byteArray = xmlModel.getStructuredDocument().get().getBytes();
				}

				if (isDelegateValidatorEnabled(file)) {
					IValidator validator = getDelegateValidator();
					if (validator != null) {
						// Validate the file:
						IValidationContext vHelper = new MyHelper(new ByteArrayInputStream(byteArray), file);
						MyReporter vReporter = new MyReporter();
						if (validator instanceof IValidatorJob) {
							((IValidatorJob) validator).validateInJob(vHelper, vReporter);
						}
						else {
							validator.validate(vHelper, vReporter);
						}
						List messages = vReporter.list;

						// set the offset and length
						updateValidationMessages(messages, document, reporter);
					}
				}
			}


			finally {
				if (xmlModel != null) {
					xmlModel.releaseFromRead();
				}
			}
		}
	}

	/**
	 * iterates through the messages and calculates a "better" offset and
	 * length
	 * 
	 * @param messages -
	 *            a List of IMessages
	 * @param document -
	 *            the document
	 * @param reporter -
	 *            the reporter the messages are to be added to
	 */
	protected void updateValidationMessages(List messages, IDOMDocument document, IReporter reporter) {
		for (int i = 0; i < messages.size(); i++) {
			IMessage message = (IMessage) messages.get(i);
			try {
				if (message.getAttribute(COLUMN_NUMBER_ATTRIBUTE) != null) {
					int column = ((Integer) message.getAttribute(COLUMN_NUMBER_ATTRIBUTE)).intValue();
					String selectionStrategy = (String) message.getAttribute(SQUIGGLE_SELECTION_STRATEGY_ATTRIBUTE);
					String nameOrValue = (String) message.getAttribute(SQUIGGLE_NAME_OR_VALUE_ATTRIBUTE);

					// convert the line and Column numbers to an offset:
					int start = document.getStructuredDocument().getLineOffset(message.getLineNumber() - 1) + column - 1;

					// calculate the "better" start and end offset:
					int[] result = computeStartAndEndLocation(start, selectionStrategy, getErrorSide(message), nameOrValue, document);
					if (result != null) {
						message.setOffset(result[0]);
						message.setLength(result[1] - result[0]);
						reporter.addMessage(this, message);
					}
				}
			}
			catch (BadLocationException e) { // this exception should not
				// occur - it is thrown if
				// trying to convert an
				// invalid line number to and
				// offset
			}

		}
	}

	/**
	 * @param delta
	 *            the IFileDelta containing the file name to get
	 * @return the IFile
	 */
	public IFile getFile(String delta) {
		IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(delta));
		if (file != null && file.exists())
		  return file;
		return null;
	}

	/**
	 * 
	 * @param file
	 *            the file to get the model for
	 * @return the file's XMLModel
	 */
	protected IDOMModel getModelForResource(IFile file) {
		IStructuredModel model = null;
		IModelManager manager = StructuredModelManager.getModelManager();

		try {
			model = manager.getModelForRead(file);
			// TODO.. HTML validator tries again to get a model a 2nd way
		}
		catch (Exception e) {
			// e.printStackTrace();
		}

		return model instanceof IDOMModel ? (IDOMModel) model : null;
	}

	/**
	 * @deprecated use computeStartEndLocation(int startOffset, String
	 *             errorMessage, String selectionStrategy, boolean leftError,
	 *             String nameOrValue, IDOMDocument document) {
	 * 
	 */
	protected int[] computeStartEndLocation(int startOffset, String errorMessage, String selectionStrategy, String nameOrValue, IDOMDocument document) {
		return computeStartAndEndLocation(startOffset, selectionStrategy, ERROR_SIDE_RIGHT, nameOrValue, document);
	}

	/**
	 * Calculates the "better" offsets.
	 * 
	 * @param startOffset -
	 *            the offset given by Xerces
	 * @param errorMessage -
	 *            the Xerces error Message
	 * @param selectionStrategy -
	 *            the selectionStrategy
	 * @param document -
	 *            the document
	 * @return int[] - position 0 has the start offset of the squiggle range,
	 *         position 1 has the endOffset
	 */
	/*
	 * The way the offsets is calculated is: - find the indexed region
	 * (element) closest to the given offset - if we are between two elements,
	 * choosing left or right element will depend on parameter 'errorSide' -
	 * based on the selectionStrategy choose the underlining strategy (eg
	 * START_TAG means underline the start tag of that element) - use
	 * information from nameOrValue and the DOM to get better offsets
	 * 
	 */
	protected int[] computeStartAndEndLocation(int startOffset, String selectionStrategy, String errorSide, String nameOrValue, IDOMDocument document) {
		try {
			int startEndPositions[] = new int[2];

			IndexedRegion region = document.getModel().getIndexedRegion(startOffset);
			IndexedRegion prevRegion = document.getModel().getIndexedRegion(startOffset - 1);

			if (prevRegion != region) {
				// if between two regions we use the 'errorSide' to understand
				// which
				// element is applicable. if we know the error has been
				// reported to the
				// right of the tag, then we can assume we need to step back
				// to the previous
				// region to land at the 'correct location. Otherwise assume
				// we're
				// exactly where we need to be.
				if (ERROR_SIDE_LEFT.equals(errorSide)) {
					region = prevRegion;
				}
			}

			// initialize start and end positions to be the start positions
			// this means if the
			// special case is not taken care of below the start and end
			// offset are set to be
			// the start of the region where the error was
			if (region != null) {
				startEndPositions[0] = region.getStartOffset();
				startEndPositions[1] = startEndPositions[0];
			}
			else { // this will message will not get added to the IReporter
				// since the length is 0
				startEndPositions[0] = 0;
				startEndPositions[1] = 0;
			}
			if (region instanceof Node) {
				Node node = (Node) region;

				if (START_TAG.equals(selectionStrategy)) {// then we want to
					// underline the opening tag
					if (node.getNodeType() == Node.ELEMENT_NODE) {
						IDOMElement element = (IDOMElement) node;
						startEndPositions[0] = element.getStartOffset() + 1;
						startEndPositions[1] = startEndPositions[0] + element.getTagName().length();
					}
				}
				else if (END_TAG.equals(selectionStrategy)) {// then we want to
					// underline the end tag
					if (node.getNodeType() == Node.ELEMENT_NODE) {
						IDOMElement element = (IDOMElement) node;
						startEndPositions[0] = element.getEndStartOffset();
						startEndPositions[1] = element.getEndOffset();
					}
				}
				else if (ATTRIBUTE_NAME.equals(selectionStrategy)) { // in
					// underline the attribute's name
					if (node.getNodeType() == Node.ELEMENT_NODE) {
						IDOMElement element = (IDOMElement) node;
						IDOMNode attributeNode = (IDOMNode) (element.getAttributeNode(nameOrValue));
						if (attributeNode != null) {
							startEndPositions[0] = attributeNode.getStartOffset();
							startEndPositions[1] = attributeNode.getStartOffset() + nameOrValue.length();
						}
					}
				}
				else if (ATTRIBUTE_VALUE.equals(selectionStrategy)) {
					// underline the attribute's value
					if (node.getNodeType() == Node.ELEMENT_NODE) {
						IDOMElement element = (IDOMElement) node;
						IDOMAttr attributeNode = (IDOMAttr) (element.getAttributeNode(nameOrValue));
						if (attributeNode != null) {
							startEndPositions[0] = attributeNode.getValueRegionStartOffset();
							startEndPositions[1] = startEndPositions[0] + attributeNode.getValueRegionText().length();
						}
					}
				}
				else if (ALL_ATTRIBUTES.equals(selectionStrategy)) {
					// underline all attributes
					if (node.getNodeType() == Node.ELEMENT_NODE) {
						IDOMElement element = (IDOMElement) node;
						NamedNodeMap attributes = element.getAttributes();
						if (attributes != null) {
							IDOMNode first = (IDOMNode) attributes.item(0);
							IDOMNode last = (IDOMNode) attributes.item(attributes.getLength() - 1);
							if ((first != null) && (last != null)) {
								startEndPositions[0] = first.getStartOffset();
								startEndPositions[1] = last.getEndOffset();
							}
						}
					}
				}
				else if (TEXT.equals(selectionStrategy)) {
					// underline the text between the tags
					if (node.getNodeType() == Node.TEXT_NODE) {
						IDOMText textNode = (IDOMText) node;
						int start = textNode.getStartOffset();
						String value = textNode.getNodeValue();
						int index = 0;
						char curChar = value.charAt(index);
						// here we are finding start offset by skipping over
						// whitespace:
						while ((curChar == '\n') || (curChar == '\t') || (curChar == '\r') || (curChar == ' ')) {
							curChar = value.charAt(index);
							index++;
						}
						if (index > 0) {
							index--;

						}
						start = start + index;
						startEndPositions[0] = start + index;
						startEndPositions[1] = start + value.trim().length();
					}
					else if (node.getNodeType() == Node.ELEMENT_NODE) {
						IDOMElement element = (IDOMElement) node;
						Node child = element.getFirstChild();
						if (child instanceof IDOMNode) {
							IDOMNode xmlChild = ((IDOMNode) child);
							startEndPositions[0] = xmlChild.getStartOffset();
							startEndPositions[1] = xmlChild.getEndOffset();
						}
					}
				}
				else if (FIRST_NON_WHITESPACE_TEXT.equals(selectionStrategy)) {
					// search through all child nodes and return range of
					// first non-whitespace
					// text node
					if (node.getNodeType() == Node.ELEMENT_NODE) {
						NodeList nodes = node.getChildNodes();
						for (int i = 0; i < nodes.getLength(); i++) {
							Node currentNode = nodes.item(i);
							if (currentNode.getNodeType() == Node.TEXT_NODE) {
								// TODO (Trung) I don't think we should call
								// getNodeValue(), trim(), length()
								// repeatedly.
								// This is inefficient, to improve use local
								// variables to store values.
								IDOMText textNode = (IDOMText) currentNode;
								if (textNode.getNodeValue().trim().length() > 0) {
									String value = textNode.getNodeValue();
									int index = 0;
									int start = textNode.getStartOffset();
									char curChar = value.charAt(index);
									// here we are finding start offset by
									// skipping over whitespace:
									while ((curChar == '\n') || (curChar == '\t') || (curChar == '\r') || (curChar == ' ')) {
										curChar = value.charAt(index);
										index++;
									}
									if (index > 0) {
										index--;

									}
									start = start + index;
									startEndPositions[0] = start;
									startEndPositions[1] = start + value.trim().length();
									break;
								}
							}

						}
					}
				}

				else if (TEXT_ENTITY_REFERENCE.equals(selectionStrategy)) {
					if (node.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
						startEndPositions[0] = region.getStartOffset();
						startEndPositions[1] = region.getEndOffset();
					}
					else if (node.getNodeType() == Node.ELEMENT_NODE) {
						/*
						 * In this case the undeclared entity might be in one
						 * of the attribute values. Search through the
						 * attributes to find the range of the undeclared
						 * entity.
						 */
						String entity = "&" + nameOrValue + ";"; //$NON-NLS-1$ //$NON-NLS-2$
						NamedNodeMap attributes = node.getAttributes();
						for (int i = 0; i < attributes.getLength(); i++) {
							IDOMAttr attr = (IDOMAttr) attributes.item(i);
							String nodeValue = attr.getNodeValue();
							int index = nodeValue.indexOf(entity);
							if (index != -1) {
								startEndPositions[0] = attr.getValueRegionStartOffset() + index + 1;
								startEndPositions[1] = startEndPositions[0] + entity.length();
							}
						}
					}

				}
				else if (VALUE_OF_ATTRIBUTE_WITH_GIVEN_VALUE.equals(selectionStrategy)) {
					// TODO (Trung) do we really need this strategy ?
					// If we know the name of the name of the attribute, we
					// can retrieve its value.
					// Hence, we can incoperate this strategy with
					// ATTRIBUTE_VALUE ?
					if (node.getNodeType() == Node.ELEMENT_NODE) {
						// here we will search through all attributes for the
						// one with the
						// with the value we want:
						// TODO (Trung) I see a potential problem here.
						// What happens when there is another attribute having
						// the same value
						// with this attribute's buggy value ?
						// Need to solve when time permits.
						NamedNodeMap attributes = node.getAttributes();
						for (int i = 0; i < attributes.getLength(); i++) {
							IDOMAttr attr = (IDOMAttr) attributes.item(i);
							String nodeValue = attr.getNodeValue().trim();
							if (nodeValue.equals(nameOrValue)) {
								startEndPositions[0] = attr.getValueRegionStartOffset() + 1;
								startEndPositions[1] = startEndPositions[0] + nodeValue.length();
								break;
							}
						}
					}
				}
			}
			return startEndPositions;
		}
		// catch (Exception e) { // e.printStackTrace();
		// }
		finally {
		}
		// return null;
	}

	/**
	 * Returns true if delegate validator is enabled based on Validation
	 * preferences
	 * 
	 * @param file
	 * @return false if delegate validator is not enabled based on Validatoin
	 *         preferences, true otherwise
	 */
	protected boolean isDelegateValidatorEnabled(IFile file) {
		return true;
	}

	protected String getErrorSide(IMessage message) {
		// note that if the ERROR_SIDE is unspecified we return the default
		// value ERROR_SIDE_LEFT
		Object value = message.getAttribute(ERROR_SIDE);
		return ERROR_SIDE_RIGHT.equals(value) ? ERROR_SIDE_RIGHT : ERROR_SIDE_LEFT;
	}
}
