/*******************************************************************************
 * Copyright (c) 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.jsdt.web.ui.internal.breakpointproviders;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.IEditorInput;
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.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.sse.ui.internal.provisional.extensions.ISourceEditingTextTools;
import org.eclipse.wst.sse.ui.internal.provisional.extensions.breakpoint.IBreakpointProvider;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
import org.eclipse.wst.xml.core.internal.provisional.contentmodel.CMNodeWrapper;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.eclipse.wst.xml.ui.internal.provisional.IDOMSourceEditingTextTools;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Abstract breakpoint provider class which implements breakpoint provider
 * interface.
 * 
 * This is a temporary class for JavaBreakpointProvider and
 * JavaScriptBreakpointProvider, and should be refactored to separate Java and
 * JavaScript parts.
 */
public abstract class AbstractBreakpointProvider implements IBreakpointProvider {

	protected static final int END_OF_LINE = -1;
	protected static final int JAVA = 1;
	protected static final int JAVASCRIPT = 2;
	private static final String[] JAVASCRIPT_LANGUAGE_KEYS = new String[] {
			"javascript", "javascript1.0", "javascript1.1_3", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			"javascript1.2", "javascript1.3", "javascript1.4", "javascript1.5", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
			"javascript1.6", "jscript", "sashscript" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	private static final String JSP_DIRECTIVE_PAGE = "jsp:directive.page"; //$NON-NLS-1$

	protected static final int NO_VALID_CONTENT = -2;
	protected static final int UNSUPPORTED = 0;

	protected static boolean contains(String[] haystack, String needle) {
		for (int i = 0; i < haystack.length; i++) {
			if (haystack[i].equals(needle)) {
				return true;
			}
		}
		return false;
	}

	/*
	 * Return the page language
	 */
	protected static int getPageLanguage(Document doc) {
		if (doc == null) {
			return UNSUPPORTED;
		}

		NodeList pageDirectives = doc.getElementsByTagName(JSP_DIRECTIVE_PAGE);
		// Search for first language directive
		for (int i = 0; i < pageDirectives.getLength(); i++) {
			Node child = pageDirectives.item(i);
			Node languageAttr = child.getAttributes().getNamedItem("language"); //$NON-NLS-1$
			if (languageAttr != null) {
				String pageLanguage = languageAttr.getNodeValue();
				if (pageLanguage == null || pageLanguage.length() == 0) {
					return UNSUPPORTED;
				}
				pageLanguage = pageLanguage.toLowerCase();
				if (contains(JAVASCRIPT_LANGUAGE_KEYS, pageLanguage)) {
					return JAVASCRIPT;
				} else if (pageLanguage.equals("java")) {
					return JAVA;
				} else {
					return UNSUPPORTED;
				}
			}
		}
		return JAVA; // Java is default if no language directive
	}

	/*
	 * Search the RegionContainer's regions looking for JSP content. If valid
	 * content is found, return the position >= 0 If no valid content is found,
	 * return NO_VALID_CONTENT. If a region starts after the line's endOffset,
	 * return END_OF_LINE.
	 */
	private static int getValidRegionPosition(IStructuredModel model,
			ITextRegionCollection regionContainer, int startOffset,
			int endOffset) {

		ITextRegionList regions = regionContainer.getRegions();
		for (int i = 0; i < regions.size(); i++) {
			ITextRegion region = regions.get(i);
			if (region instanceof ITextRegionCollection) {
				int validPosition = getValidRegionPosition(model,
						(ITextRegionCollection) region, startOffset, endOffset);
				if (validPosition == END_OF_LINE || validPosition >= 0) {
					return validPosition;
				}
			} else {
				// region must be at least partially on selected line
				if (regionContainer.getEndOffset(region) > startOffset) {

					int regionStartOffset = regionContainer
							.getStartOffset(region);
					// if region starts after line's endOffset, we're done
					// searching
					if (regionStartOffset > endOffset) {
						return END_OF_LINE;
					}

					// If region is JSP content, make sure the language is
					// Java not Javascript by
					// checking the content assist adapter's type.
					if (region.getType().equals(
							"DOMJSPRegionContexts.JSP_CONTENT")) {
						// DWM: this logic is not incorrect ... given changes
						// to adapters, etc.
						// but probably don't need anything here, since both
						// Java and JavaScript
						// are supported in V5.

						// nsd_TODO: verify this!!!

						// INodeNotifier notifier =
						// (INodeNotifier)model.getNode(region.getStartOffset());
						// IAdapterFactory factory =
						// model.getFactoryRegistry().getFactoryFor(ContentAssistAdapter.class);
						// if(factory instanceof
						// HTMLContentAssistAdapterFactory) {
						// INodeAdapter adapter =
						// ((HTMLContentAssistAdapterFactory)factory).createAdapter(notifier,
						// region);
						// if(adapter != null && adapter instanceof
						// JSPJavaContentAssistAdapter)

						if (regionStartOffset > startOffset) {
							return regionStartOffset;
						} else {
							return startOffset;
							// }
						}
					}
					// a custom tag, jsp:useBean, getproperty or setproperty
					// statement is also a valid breakpoint location
					else if (region.getType().equals(
							DOMRegionContext.XML_TAG_NAME)
							&& (isCustomTagRegion(model
									.getIndexedRegion(regionStartOffset))
									|| regionContainer.getText(region).equals(
											"JSP12Namespace.ElementName.USEBEAN")
									|| regionContainer
											.getText(region)
											.equals(
													"JSP12Namespace.ElementName.GETPROPERTY") || regionContainer
									.getText(region)
									.equals(
											"JSP12Namespace.ElementName.SETPROPERTY"))) {

						if (regionStartOffset > startOffset) {
							return regionStartOffset;
						} else {
							return startOffset;
						}
					} else {
						// Defect #241090, the Text Nodes inside of JSP
						// scriptlets, expressions, and declarations are valid
						// breakpoint-able locations
						boolean isCodeNode = false;
						IndexedRegion node = model
								.getIndexedRegion(regionStartOffset);
						if (node != null && node instanceof Node) {
							Node domNode = (Node) node;
							Node root = domNode.getOwnerDocument()
									.getDocumentElement();
							if (root != null
									&& root.getNodeName().equals(
											"JSP12Namespace.ElementName.ROOT")
									&& domNode.getNodeType() == Node.TEXT_NODE
									&& domNode.getParentNode() != null) {
								String parentName = domNode.getParentNode()
										.getNodeName();
								isCodeNode = parentName
										.equals("JSP12Namespace.ElementName.SCRIPTLET")
										|| parentName
												.equals("JSP12Namespace.ElementName.EXPRESSION")
										|| parentName
												.equals("JSP12Namespace.ElementName.DECLARATION");
							}
						}
						if (isCodeNode) {
							if (regionStartOffset > startOffset) {
								return regionStartOffset;
							} else {
								return startOffset;
							}
						}
					}
				}
			}
		}
		return NO_VALID_CONTENT;
	}

	private static boolean isCustomTagRegion(IndexedRegion node) {

		if (node instanceof Element) {
			Element xmlElement = (Element) node;
			ModelQuery mq = ModelQueryUtil.getModelQuery(xmlElement
					.getOwnerDocument());
			CMElementDeclaration decl = mq.getCMElementDeclaration(xmlElement);
			if (decl instanceof CMNodeWrapper) {
				CMNode cmNode = ((CMNodeWrapper) decl).getOriginNode();
				//return cmNode instanceof TLDElementDeclaration;
			}
		}
		return false;
	}

	private ISourceEditingTextTools fSourceEditingTextTools;

	protected IResource getEditorInputResource(IEditorInput input) {
		IResource resource = (IResource) input.getAdapter(IFile.class);
		if (resource == null) {
			resource = (IResource) input.getAdapter(IResource.class);
		}
		return resource;
	}

	public ISourceEditingTextTools getSourceEditingTextTools() {
		return fSourceEditingTextTools;
	}

	protected int getValidPosition(IDocument idoc, int lineNumber) {
		if (!(getSourceEditingTextTools() instanceof IDOMSourceEditingTextTools)) {
			return NO_VALID_CONTENT;
		}
		if (idoc == null) {
			return NO_VALID_CONTENT;
		}

		int startOffset, endOffset;
		try {
			startOffset = idoc.getLineOffset(lineNumber - 1);
			endOffset = idoc.getLineOffset(lineNumber) - 1;

			if (idoc == null) {
				return NO_VALID_CONTENT;
			}
			String lineText = idoc.get(startOffset, endOffset - startOffset)
					.trim();

			// blank lines or lines with only an open or close brace or
			// scriptlet tag cannot have a breakpoint
			if (lineText.equals("") || lineText.equals("{") || //$NON-NLS-2$//$NON-NLS-1$
					lineText.equals("}") || lineText.equals("<%")) {
				return NO_VALID_CONTENT;
			}
		} catch (BadLocationException e) {
			return NO_VALID_CONTENT;
		}

		IStructuredDocumentRegion flatNode = ((IStructuredDocument) idoc)
				.getRegionAtCharacterOffset(startOffset);
		// go through the node's regions looking for JSP content
		// until reaching the end of the line
		while (flatNode != null) {
			int validPosition = getValidRegionPosition(
					((IDOMDocument) ((IDOMSourceEditingTextTools) getSourceEditingTextTools())
							.getDOMDocument()).getModel(), flatNode,
					startOffset, endOffset);

			if (validPosition == END_OF_LINE) {
				return NO_VALID_CONTENT;
			}

			if (validPosition >= 0) {
				return validPosition;
			}

			flatNode = flatNode.getNext();
		}
		return NO_VALID_CONTENT;
	}

	public void setSourceEditingTextTools(
			ISourceEditingTextTools sourceEditingTextTools) {
		fSourceEditingTextTools = sourceEditingTextTools;
	}
}
