package org.eclipse.wst.html.ui.internal.hyperlink;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.URLHyperlink;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverPlugin;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.util.StringUtils;
import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDataType;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMNamespaceHelper;
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.w3c.dom.Attr;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

/**
 * Detects hyperlinks in XML tags. Includes detection in DOCTYPE and attribute
 * values. Resolves references to schemas, dtds, etc using the Common URI
 * Resolver.
 * 
 */
class XMLHyperlinkDetector implements IHyperlinkDetector {
	// copies of this class exist in:
	// org.eclipse.wst.xml.ui.internal.hyperlink
	// org.eclipse.wst.html.ui.internal.hyperlink
	// org.eclipse.jst.jsp.ui.internal.hyperlink
	
	private final String NO_NAMESPACE_SCHEMA_LOCATION = "noNamespaceSchemaLocation"; //$NON-NLS-1$
	private final String SCHEMA_LOCATION = "schemaLocation"; //$NON-NLS-1$
	private final String XMLNS = "xmlns"; //$NON-NLS-1$
	private final String XSI_NAMESPACE_URI = "http://www.w3.org/2001/XMLSchema-instance"; //$NON-NLS-1$
	private final String HTTP_PROTOCOL = "http://";//$NON-NLS-1$

	public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
		// for now, only capable of creating 1 hyperlink
		List hyperlinks = new ArrayList(0);

		if (region != null && textViewer != null) {
			IDocument document = textViewer.getDocument();
			Node currentNode = getCurrentNode(document, region.getOffset());
			if (currentNode != null) {
				String uriString = null;
				if (currentNode.getNodeType() == Node.DOCUMENT_TYPE_NODE) {
					// doctype nodes
					uriString = getURIString(currentNode, document);
				}
				else if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
					// element nodes
					Attr currentAttr = getCurrentAttrNode(currentNode, region.getOffset());
					if (currentAttr != null) {
						// try to find link for current attribute
						// resolve attribute value
						uriString = getURIString(currentAttr, document);
						// verify validity of uri string
						if (!isValidURI(uriString))
							// reset current attribute
							currentAttr = null;
					}
					if (currentAttr == null) {
						// try to find a linkable attribute within element
						currentAttr = getLinkableAttr((Element) currentNode);
						if (currentAttr != null) {
							uriString = getURIString(currentAttr, document);
						}
					}
					currentNode = currentAttr;
				}
				// try to create hyperlink from information gathered
				if (uriString != null && currentNode != null && isValidURI(uriString)) {
					IRegion hyperlinkRegion = getHyperlinkRegion(currentNode);
					IHyperlink hyperlink = createHyperlink(uriString, hyperlinkRegion, document, currentNode);
					if (hyperlink != null) {
						hyperlinks.add(hyperlink);
					}
				}
			}
		}
		if (hyperlinks.size() == 0)
			return null;
		return (IHyperlink[]) hyperlinks.toArray(new IHyperlink[0]);
	}

	/**
	 * Create the appropriate hyperlink
	 * 
	 * @param uriString
	 * @param hyperlinkRegion
	 * @return IHyperlink
	 */
	private IHyperlink createHyperlink(String uriString, IRegion hyperlinkRegion, IDocument document, Node node) {
		IHyperlink link = null;

		if (uriString != null) {
			String temp = uriString.toLowerCase();
			if (temp.startsWith(HTTP_PROTOCOL)) {
				// this is a URLHyperlink since this is a web address
				link = new URLHyperlink(hyperlinkRegion, uriString);
			}
			else {
				// try to locate the file in the workspace
				IFile file = getFile(uriString);
				if (file != null && file.exists()) {
					// this is a WorkspaceFileHyperlink since file exists in
					// workspace
					link = new WorkspaceFileHyperlink(hyperlinkRegion, file);
				}
				else {
					// this is an ExternalFileHyperlink since file does not
					// exist
					// in workspace
					File externalFile = new File(uriString);
					link = new ExternalFileHyperlink(hyperlinkRegion, externalFile);
				}
			}
		}

		return link;
	}

	private IRegion getHyperlinkRegion(Node node) {
		IRegion hyperRegion = null;

		if (node != null) {
			short nodeType = node.getNodeType();
			if (nodeType == Node.DOCUMENT_TYPE_NODE) {
				// handle doc type node
				IDOMNode docNode = (IDOMNode) node;
				hyperRegion = new Region(docNode.getStartOffset(), docNode.getEndOffset() - docNode.getStartOffset());
			}
			else if (nodeType == Node.ATTRIBUTE_NODE) {
				// handle attribute nodes
				IDOMAttr att = (IDOMAttr) node;
				// do not include quotes in attribute value region
				int regOffset = att.getValueRegionStartOffset();
				int regLength = att.getValueRegion().getTextLength();
				String attValue = att.getValueRegionText();
				if (StringUtils.isQuoted(attValue)) {
					regOffset = ++regOffset;
					regLength = regLength - 2;
				}
				hyperRegion = new Region(regOffset, regLength);
			}
		}
		return hyperRegion;
	}

	/**
	 * Returns the URI string
	 * 
	 * @param node -
	 *            assumes not null
	 */
	protected String getURIString(Node node, IDocument document) {
		String resolvedURI = null;
		// need the base location, publicId, and systemId for URIResolver
		String baseLoc = null;
		String publicId = null;
		String systemId = null;

		short nodeType = node.getNodeType();
		// handle doc type node
		if (nodeType == Node.DOCUMENT_TYPE_NODE) {
			baseLoc = getBaseLocation(document);
			publicId = ((DocumentType) node).getPublicId();
			systemId = ((DocumentType) node).getSystemId();
		}
		else if (nodeType == Node.ATTRIBUTE_NODE) {
			// handle attribute node
			Attr attrNode = (Attr) node;
			baseLoc = getBaseLocation(document);
			String attrName = attrNode.getName();
			String attrValue = attrNode.getValue();
			attrValue = StringUtils.strip(attrValue);

			// handle schemaLocation attribute
			String prefix = DOMNamespaceHelper.getPrefix(attrName);
			String unprefixedName = DOMNamespaceHelper.getUnprefixedName(attrName);
			if ((XMLNS.equals(prefix)) || (XMLNS.equals(unprefixedName))) {
				publicId = attrValue;
				systemId = getLocationHint(attrNode.getOwnerElement(), publicId);
			}
			else if ((XSI_NAMESPACE_URI.equals(DOMNamespaceHelper.getNamespaceURI(attrNode))) && (SCHEMA_LOCATION.equals(unprefixedName))) {
				// for now just use the first pair
				// need to look into being more precise
				StringTokenizer st = new StringTokenizer(attrValue);
				publicId = st.hasMoreTokens() ? st.nextToken() : null;
				systemId = st.hasMoreTokens() ? st.nextToken() : null;
				// else check if xmlns publicId = value
			}
			else {
				systemId = attrValue;
			}
		}

		resolvedURI = resolveURI(baseLoc, publicId, systemId);
		return resolvedURI;
	}

	/**
	 * Returns an IFile from the given uri if possible, null if cannot find
	 * file from uri.
	 * 
	 * @param fileString
	 *            file system path
	 * @return returns IFile if fileString exists in the workspace
	 */
	private IFile getFile(String fileString) {
		IFile file = null;

		if (fileString != null) {
			IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(new Path(fileString));
			for (int i = 0; i < files.length && file == null; i++)
				if (files[i].exists())
					file = files[i];
		}

		return file;
	}

	/**
	 * Checks to see if the given attribute is openable. Attribute is openable
	 * if it is a namespace declaration attribute or if the attribute value is
	 * of type URI.
	 * 
	 * @param attr
	 *            cannot be null
	 * @param cmElement
	 *            CMElementDeclaration associated with the attribute (can be
	 *            null)
	 * @return true if this attribute is "openOn-able" false otherwise
	 */
	private boolean isLinkableAttr(Attr attr, CMElementDeclaration cmElement) {
		String attrName = attr.getName();
		String prefix = DOMNamespaceHelper.getPrefix(attrName);
		String unprefixedName = DOMNamespaceHelper.getUnprefixedName(attrName);
		// determine if attribute is namespace declaration
		if ((XMLNS.equals(prefix)) || (XMLNS.equals(unprefixedName)))
			return true;

		// determine if attribute contains schema location
		if ((XSI_NAMESPACE_URI.equals(DOMNamespaceHelper.getNamespaceURI(attr))) && ((SCHEMA_LOCATION.equals(unprefixedName)) || (NO_NAMESPACE_SCHEMA_LOCATION.equals(unprefixedName))))
			return true;

		// determine if attribute value is of type URI
		if (cmElement != null) {
			CMAttributeDeclaration attrDecl = (CMAttributeDeclaration) cmElement.getAttributes().getNamedItem(attrName);
			if ((attrDecl != null) && (attrDecl.getAttrType() != null) && (CMDataType.URI.equals(attrDecl.getAttrType().getDataTypeName()))) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Attempts to find an attribute within element that is openable.
	 * 
	 * @param element -
	 *            cannot be null
	 * @return Attr attribute that can be used for open on, null if no
	 *         attribute could be found
	 */
	private Attr getLinkableAttr(Element element) {
		CMElementDeclaration ed = getCMElementDeclaration(element);
		// get the list of attributes for this node
		NamedNodeMap attrs = element.getAttributes();
		for (int i = 0; i < attrs.getLength(); ++i) {
			// check if this attribute is "openOn-able"
			Attr att = (Attr) attrs.item(i);
			if (isLinkableAttr(att, ed)) {
				return att;
			}
		}
		return null;
	}

	/**
	 * Get the CMElementDeclaration for an element
	 * 
	 * @param element
	 * @return CMElementDeclaration
	 */
	private CMElementDeclaration getCMElementDeclaration(Element element) {
		CMElementDeclaration ed = null;

		ModelQuery mq = ModelQueryUtil.getModelQuery(element.getOwnerDocument());
		if (mq != null) {
			ed = mq.getCMElementDeclaration(element);
		}
		return ed;
	}

	/**
	 * Returns the attribute node within node at offset
	 * 
	 * @param node
	 * @param offset
	 * @return Attr
	 */
	private Attr getCurrentAttrNode(Node node, int offset) {
		if ((node instanceof IndexedRegion) && ((IndexedRegion) node).contains(offset) && (node.hasAttributes())) {
			NamedNodeMap attrs = node.getAttributes();
			// go through each attribute in node and if attribute contains
			// offset, return that attribute
			for (int i = 0; i < attrs.getLength(); ++i) {
				// assumption that if parent node is of type IndexedRegion,
				// then its attributes will also be of type IndexedRegion
				IndexedRegion attRegion = (IndexedRegion) attrs.item(i);
				if (attRegion.contains(offset)) {
					return (Attr) attrs.item(i);
				}
			}
		}
		return null;
	}

	/**
	 * Returns the node the cursor is currently on in the document. null if no
	 * node is selected
	 * 
	 * @param offset
	 * @return Node either element, doctype, text, or null
	 */
	private Node getCurrentNode(IDocument document, int offset) {
		// get the current node at the offset (returns either: element,
		// doctype, text)
		IndexedRegion inode = null;
		IStructuredModel sModel = null;
		try {
			sModel = StructuredModelManager.getModelManager().getExistingModelForRead(document);
			inode = sModel.getIndexedRegion(offset);
			if (inode == null)
				inode = sModel.getIndexedRegion(offset - 1);
		}
		finally {
			if (sModel != null)
				sModel.releaseFromRead();
		}

		if (inode instanceof Node) {
			return (Node) inode;
		}
		return null;
	}

	/**
	 * Get the base location from the current model (local file system)
	 */
	private String getBaseLocation(IDocument document) {
		String baseLoc = null;

		// get the base location from the current model
		IStructuredModel sModel = null;
		try {
			sModel = StructuredModelManager.getModelManager().getExistingModelForRead(document);
			if (sModel != null) {
				IPath location = new Path(sModel.getBaseLocation());
				if (location.toFile().exists()) {
					baseLoc = location.toString();
				}
				else {
					IPath basePath = new Path(sModel.getBaseLocation());
					if(basePath.segmentCount() > 1)
						baseLoc = ResourcesPlugin.getWorkspace().getRoot().getFile(basePath).getLocation().toString();
					else
						baseLoc = ResourcesPlugin.getWorkspace().getRoot().getLocation().append(basePath).toString();
				}
			}
		}
		finally {
			if (sModel != null) {
				sModel.releaseFromRead();
			}
		}
		return baseLoc;
	}

	/**
	 * Checks whether the given uriString is really pointing to a file
	 * 
	 * @param uriString
	 * @return boolean
	 */
	private boolean isValidURI(String uriString) {
		boolean isValid = false;

		if (uriString != null) {
			// first do a quick check to see if this is some sort of http://
			String tempString = uriString.toLowerCase();
			if (tempString.startsWith(HTTP_PROTOCOL))
				isValid = true;
			else {
				File file = new File(uriString);
				try {
					URI uri = new URI(uriString);
					file = new File(uri);
				}
				catch (URISyntaxException e) {
					// it is okay that a uri could not be created out of
					// uriString
				}
				catch (IllegalArgumentException e) {
					// it is okay that file could not be created out of uri
				}
				isValid = file.exists();
			}
		}
		return isValid;
	}

	/**
	 * Resolves the given URI information
	 * 
	 * @param baseLocation
	 * @param publicId
	 * @param systemId
	 * @return String resolved uri.
	 */
	private String resolveURI(String baseLocation, String publicId, String systemId) {
		// dont resolve if there's nothing to resolve
		if ((baseLocation == null) && (publicId == null) && (systemId == null))
			return null;
		return URIResolverPlugin.createResolver().resolve(baseLocation, publicId, systemId);
	}

	/**
	 * Find the location hint for the given namespaceURI if it exists
	 * 
	 * @param elementNode -
	 *            cannot be null
	 * @param namespaceURI -
	 *            cannot be null
	 * @return location hint (systemId) if it was found, null otherwise
	 */
	private String getLocationHint(Element elementNode, String namespaceURI) {
		Attr schemaLocNode = elementNode.getAttributeNodeNS(XSI_NAMESPACE_URI, SCHEMA_LOCATION);
		if (schemaLocNode != null) {
			StringTokenizer st = new StringTokenizer(schemaLocNode.getValue());
			while (st.hasMoreTokens()) {
				String publicId = st.hasMoreTokens() ? st.nextToken() : null;
				String systemId = st.hasMoreTokens() ? st.nextToken() : null;
				// found location hint
				if (namespaceURI.equalsIgnoreCase(publicId))
					return systemId;
			}
		}
		return null;
	}
}
