/*******************************************************************************
 * Copyright (c) 2004-2006 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.core.internal.document;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

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.core.runtime.Platform;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.wst.jsdt.web.core.internal.Logger;
import org.eclipse.wst.jsdt.web.core.internal.contentproperties.JSPFContentProperties;
import org.eclipse.wst.jsdt.web.core.internal.modelhandler.EmbeddedTypeStateData;
import org.eclipse.wst.jsdt.web.core.internal.provisional.contenttype.ContentTypeIdForJSP;
import org.eclipse.wst.jsdt.web.core.internal.provisional.contenttype.IContentDescriptionForJSP;
import org.eclipse.wst.jsdt.web.core.internal.text.StructuredTextPartitionerForJSP;
import org.eclipse.wst.html.core.internal.provisional.contenttype.ContentTypeFamilyForHTML;
import org.eclipse.wst.sse.core.internal.ltk.modelhandler.EmbeddedTypeHandler;
import org.eclipse.wst.sse.core.internal.modelhandler.EmbeddedTypeRegistry;
import org.eclipse.wst.sse.core.internal.modelhandler.EmbeddedTypeRegistryImpl;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapterFactory;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredPartitioning;
import org.eclipse.wst.sse.core.internal.util.Debug;
import org.eclipse.wst.sse.core.internal.util.DocumentInputStream;
import org.eclipse.wst.sse.core.utils.StringUtils;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

import com.ibm.icu.util.StringTokenizer;

/**
 * This class has the responsibility to provide an embedded factory registry for
 * JSP Aware INodeAdapter Factories to use.
 * 
 * Typically, the embedded type is to be considered a feature of the document,
 * so JSP Aware AdpaterFactories should call
 * getAdapter(PageDirectiveAdapter.class) directoy on the document (or owning
 * document) node.
 */
public class PageDirectiveAdapterImpl implements PageDirectiveAdapter {

	protected static final String STR_CHARSET = "charset"; //$NON-NLS-1$
	private final static Object adapterType = PageDirectiveAdapter.class;
	private IStructuredModel model;
	protected final String[] JAVASCRIPT_LANGUAGE_KEYS = new String[] {
			"javascript", "javascript1.0", "javascript1.1_3", "javascript1.2", "javascript1.3", "javascript1.4", "javascript1.5", "javascript1.6", "jscript", "sashscript" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
	protected final String[] JAVA_LANGUAGE_KEYS = new String[] { "java" }; //$NON-NLS-1$

	/**
	 * Constructor for PageDirectiveAdapterImpl.
	 */
	public PageDirectiveAdapterImpl(INodeNotifier target) {
		super();
		notifierAtCreation = target;
		// we need to remember our instance of model,
		// in case we need to "signal" a re-init needed.
		if (target instanceof IDOMNode) {
			IDOMNode node = (IDOMNode) target;
			model = node.getModel();
		}

	}

	/**
	 * parses the full contentType value into its two parts the contentType, and
	 * the charset, if present. Note: this method is a lightly modified version
	 * of a method in AbstractHeadParser. There, we're mostly interested in the
	 * charset part of contentTypeValue. Here, we're mostly interested in the
	 * mimeType part.
	 */
	private String getMimeTypeFromContentTypeValue(String contentTypeValue) {
		if (contentTypeValue == null) {
			return null;
		}
		String cleanContentTypeValue = StringUtils
				.stripNonLetterDigits(contentTypeValue);
		StringTokenizer tokenizer = new StringTokenizer(cleanContentTypeValue,
				";= \t\n\r\f"); //$NON-NLS-1$
		int tLen = tokenizer.countTokens();
		// if contains encoding should have three tokens, the mimetype, the
		// word 'charset', and the encoding value
		String[] tokens = new String[tLen];
		int j = 0;
		while (tokenizer.hasMoreTokens()) {
			tokens[j] = tokenizer.nextToken();
			j++;
		}
		// 
		// Following is the common form for target expression
		// <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
		// But apparrently is also valid without the content type there,
		// just the charset, as follows:
		// <META http-equiv="Content-Type" content="charset=UTF-8">
		// So we'll loop through tokens and key off of 'charset'

		int charsetPos = -1;
		for (int i = 0; i < tokens.length; i++) {
			if (tokens[i].equalsIgnoreCase(STR_CHARSET)) {
				charsetPos = i;
				break;
			}
		}
		// String charset = null;
		String contentType = null;
		if (charsetPos > -1) {
			// case where charset was present
			// int charsetValuePos = charsetPos + 1;
			// if (charsetValuePos < tokens.length) {
			// charset = tokens[charsetValuePos];
			// }
			int contentTypeValuePos = charsetPos - 1;
			if (contentTypeValuePos > -1) {
				contentType = tokens[contentTypeValuePos];
			}
		} else {
			// charset was not present, so if there's
			// a value, we assume its the contentType value
			if (tokens.length > 0) {
				contentType = tokens[0];
			}
		}
		return contentType;
	}

	private EmbeddedTypeHandler embeddedTypeHandler;
	private List embeddedFactoryRegistry = new ArrayList();
	private String cachedLanguage;
	private String cachedContentType;
	private INodeNotifier notifierAtCreation;

	private int firstLanguagePosition = -1;
	private int firstContentTypePosition = -1;

	/*
	 * @see INodeAdapter#isAdapterForType(Object)
	 */
	public boolean isAdapterForType(Object type) {
		return (type == adapterType);
	}

	/*
	 * @see INodeAdapter#notifyChanged(INodeNotifier, int, Object, Object,
	 *      Object, int)
	 */
	public void notifyChanged(INodeNotifier notifier, int eventType,
			Object changedFeature, Object oldValue, Object newValue, int pos) {
	}

	public void setEmbeddedType(EmbeddedTypeHandler handler) {
		// if really the same handler, no need for further processing
		if (embeddedTypeHandler == handler) {
			return;
		}
		// then one exists, and the new one is truely different, so we need to
		// release and remove current factories
		if (embeddedTypeHandler != null) {
			Iterator list = embeddedFactoryRegistry.iterator();
			while (list.hasNext()) {
				INodeAdapterFactory factory = (INodeAdapterFactory) list.next();
				factory.release();
			}

			embeddedFactoryRegistry.clear();
		}

		embeddedTypeHandler = handler;
		// when the handler is set, "transfer" its factories to our own list.
		// note: our own list may also be added to else where, such as on
		// "editor side".
		if (embeddedTypeHandler != null) {
			Iterator iterator = embeddedTypeHandler.getAdapterFactories()
					.iterator();
			while (iterator.hasNext()) {
				INodeAdapterFactory factory = (INodeAdapterFactory) iterator
						.next();
				embeddedFactoryRegistry.add(factory);
			}
		}
	}

	/**
	 * @see PageDirectiveAdapter#adapt(INodeNotifier, Object)
	 */
	public INodeAdapter adapt(INodeNotifier notifier, Object type) {
		INodeAdapter result = null;
		// if embeddedContentType hasn't been set,
		// then we can not adapt it.
		if (embeddedTypeHandler != null) {
			if (embeddedFactoryRegistry != null) {
				Iterator iterator = embeddedFactoryRegistry.iterator();
				INodeAdapterFactory factory = null;
				while (iterator.hasNext()) {
					factory = (INodeAdapterFactory) iterator.next();
					if (factory.isFactoryForType(type)) {
						result = factory.adapt(notifier);
						break;
					}
				}
			}
		}
		return result;

	}

	/**
	 * @see PageDirectiveAdapter#getEmbeddedType()
	 */
	public EmbeddedTypeHandler getEmbeddedType() {
		if (embeddedTypeHandler == null) {
			embeddedTypeHandler = getDefaultEmbeddedType();
		}
		return embeddedTypeHandler;
	}

	public void addEmbeddedFactory(INodeAdapterFactory factory) {
		// should we check if already exists in list?
		embeddedFactoryRegistry.add(factory);
	}

	// /**
	// * Used by PageDirectiveWatchers to signal that some important attribute
	// has changed, and
	// * any cached values should be re-calcuated
	// */
	// void changed() {
	// // we won't actually check if change is needed, if the model state is
	// already changing.
	// if (!model.isReinitializationNeeded()) {
	// // go through our list of page watcher adapters, and updates the
	// attributes
	// // we're interested in, if and only if they are the earliest occurance
	// in the resource
	// String potentialContentType = null;
	// String potentialLanguage = null;
	// int contentTypePosition = -1;
	// int languagePosition = -1;
	// Iterator iterator = pageDirectiveWatchers.iterator();
	// while (iterator.hasNext()) {
	// PageDirectiveWatcher pdWatcher = (PageDirectiveWatcher)
	// iterator.next();
	// String contentType = pdWatcher.getContentType();
	// String language = pdWatcher.getLanguage();
	// int offset = pdWatcher.getOffset();
	// if (potentialContentType == null || (hasValue(contentType) && (offset <
	// contentTypePosition))) {
	// potentialContentType = contentType;
	// contentTypePosition = offset;
	// }
	// }
	// // now we have the best candiates for cached values, let's see if
	// they've really changed from
	// // what we had. If so, note we go through the setters so side effects
	// can take place there.
	// potentialContentType =
	// getMimeTypeFromContentTypeValue(potentialContentType);
	// if (potentialContentType == null || potentialContentType.length() == 0)
	// {
	// //potentialContentType = getDefaultContentType();
	// } else {
	// setCachedContentType(potentialContentType);
	// }
	//
	// if (potentialLanguage != null && hasValue(potentialLanguage)) {
	// setCachedLanguage(potentialLanguage);
	// }
	// }
	// }
	void changedContentType(int elementOffset, String newValue) {
		// only need to process if this new value is
		// earlier in the file than our current value
		if (firstContentTypePosition == -1
				|| elementOffset <= firstContentTypePosition) {
			// dw_TODO: update embedded partitioner in JSP document
			// partitioner
			// nsd_TODO: update embedded partitioner in JSP document
			// partitioner

			// no need to change current value, if we're told some
			// earlier value is null or blank (sounds like an error, anyway)
			if (hasValue(newValue)) {
				firstContentTypePosition = elementOffset;
				String potentialContentType = getMimeTypeFromContentTypeValue(newValue);
				// only do the set processing if different
				// from what it already is
				// if (!potentialContentType.equalsIgnoreCase(cachedLanguage))
				// {
				setCachedContentType(potentialContentType);
				// }
			}
		}
	}

	/**
	 * Used by PageDirectiveWatchers to signal that some important attribute has
	 * changed, and any cached values should be re-calcuated
	 */
	void changedLanguage(int elementOffset, String newValue) {
		// only need to process if this new value is
		// earlier in the file than our current value
		// has to be less than or equal to, in case our previous earliest one,
		// is itself changing!
		if (firstLanguagePosition == -1
				|| elementOffset <= firstLanguagePosition) {

			// no need to change current value, if we're told some
			// earlier value is null or blank (sounds like an error, anyway)
			if (hasValue(newValue)) {
				firstLanguagePosition = elementOffset;
				// only do the set processing if different
				// from what it already is
				if (!newValue.equalsIgnoreCase(cachedLanguage)) {
					setCachedLanguage(newValue);
				}
			}

			// dw_TODO: set language in document partitioner
			// nsd_TODO: set language in document partitioner
		}
	}

	/**
	 * Used by PageDirectiveWatchers to signal that some important attribute has
	 * changed, and any cached values should be re-calcuated
	 */
	void changedPageEncoding(int elementOffset, String newValue) {

		// we don't currently track active value, since
		// just need during read and write (where its
		// calculated. We will need in future, to
		// acurately clone a model and to display
		// "current encoding" to user in status bar.
	}

	/**
	 * Method hasValue.
	 * 
	 * @param contentType
	 * @return boolean
	 */
	private boolean hasValue(String value) {
		if (value != null && value.length() > 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Returns the cachedContentType.
	 * 
	 * @return String
	 */
	public String getContentType() {
		if (cachedContentType == null) {
			cachedContentType = getDefaultContentType();
		}
		return cachedContentType;
	}

	/**
	 * Method getDefaultContentType.
	 * 
	 * @return String
	 */
	private String getDefaultContentType() {
		String type = null;
		IFile file = getFile(model);
		if (file != null) {
			type = JSPFContentProperties.getProperty(
					JSPFContentProperties.JSPCONTENTTYPE, file, true);
		}
		// BUG136468
		if (type == null) {
			type = "text/html"; //$NON-NLS-1$
		}
		return type;
	}

	/**
	 * Returns the cachedLanguage.
	 * 
	 * @return String
	 */
	public String getLanguage() {
		if (cachedLanguage == null) {
			cachedLanguage = getDefaultLanguage();
		}
		return cachedLanguage;
	}

	/**
	 * Method getDefaultLanguage.
	 * 
	 * @return String
	 */
	private String getDefaultLanguage() {
		String language = null;
		IFile file = getFile(model);
		if (file != null) {
			language = JSPFContentProperties.getProperty(
					JSPFContentProperties.JSPLANGUAGE, file, true);
		}
		// BUG136468
		if (language == null) {
			language = "java"; //$NON-NLS-1$
		}
		return language;
	}

	/**
	 * Sets the cachedContentType.
	 * 
	 * @param cachedContentType
	 *            The cachedContentType to set
	 */
	public void setCachedContentType(String newContentType) {
		/*
		 * if the passed in value is the same as existing, there's nothing to
		 * do. if its different, then we need to change the contentHandler as
		 * well and, more to the point, signal a re-initializtation is needed.
		 * 
		 * Note: if the value we're getting set to does not have a handler in
		 * the registry, we'll actually not set it to null or anything, we'll
		 * just continue on with the one we have. This is pretty important to
		 * avoid re-initializing on every key stroke if someone is typing in a
		 * new content type, but haven't yet finished the whole "word". However,
		 * if an contentType is not recognized, the registry returns the one for
		 * XML.
		 */

		/* set the actual value first, the rest is "side effect" */
		this.cachedContentType = newContentType;

		/* see if we need to update embedded handler */

		/*
		 * If the document is a type of XHTML, we do not use the page
		 * directive's contentType to determine the embedded type ... its XHTML!
		 * ... and, eventually, the DOCTYPE adapter should determine if/when it
		 * needs to change.
		 */

		/* just safety check, can be removed later, early in release cycle */
		if (model == null) {
			// throw IllegalStateException("model should never be null in
			// PageDirective Adapter");
			Logger.log(Logger.ERROR,
					"model should never be null in PageDirective Adapter");
			return;
		}

		EmbeddedTypeHandler potentialNewandler = null;
		IContentDescription contentDescription = getContentDescription(model
				.getStructuredDocument());
		Object prop = contentDescription
				.getProperty(IContentDescriptionForJSP.CONTENT_FAMILY_ATTRIBUTE);
		if (prop != null) {
			if (ContentTypeFamilyForHTML.HTML_FAMILY.equals(prop)) {
				potentialNewandler = EmbeddedTypeRegistryImpl.getInstance()
						.getTypeFor("text/html");
			}
		}

		if (potentialNewandler == null) {
			/*
			 * getHandler should always return something (never null), based on
			 * the rules in the factory.
			 */
			potentialNewandler = getHandlerFor(this.cachedContentType);
		}
		/*
		 * we do this check for re-init here, instead of in setEmbeddedType,
		 * since setEmbeddedType is called during the normal initializtion
		 * process, when re-init is not needed (since there is no content)
		 */
		if (embeddedTypeHandler == null) {
			setEmbeddedType(potentialNewandler);
		} else if (potentialNewandler != null
				&& embeddedTypeHandler != potentialNewandler) {
			/*
			 * changing this embedded handler here may be in the middle of a
			 * notify loop. That's why we set that "it's needed". Then the model
			 * decides when its "safe" to actually do the re-init.
			 * 
			 * be sure to hold oldHandler in temp var or else setEmbeddedType
			 * will "reset" it before modelReinitNeeded(oldHandler, handler) is
			 * called
			 * 
			 */
			EmbeddedTypeHandler oldHandler = embeddedTypeHandler;
			setEmbeddedType(potentialNewandler);
			modelReinitNeeded(oldHandler, potentialNewandler);
		}

	}

	/**
	 * This method is used to re-init based on embeddedTypeHandler changing. It
	 * is given priority over the language change, since there its more
	 * important to have old and new handlers's in the stateData field.
	 */
	private void modelReinitNeeded(EmbeddedTypeHandler oldHandler,
			EmbeddedTypeHandler newHandler) {
		if (model.isReinitializationNeeded()) {
			System.out.println("already being initialized"); //$NON-NLS-1$
		}

		try {
			model.aboutToChangeModel();
			model.setReinitializeStateData(new EmbeddedTypeStateData(
					oldHandler, newHandler));
			model.setReinitializeNeeded(true);
		} finally {
			model.changedModel();
		}
	}

	/**
	 * Method modelReinitNeeded.
	 */
	private void modelReinitNeeded(String oldlanguage, String newLanguage) {
		// bit of a short cut for now .... we dont' need language at the
		// moment,
		// but should set the state data
		if (model.isReinitializationNeeded()) {
			if (Debug.displayWarnings) {
				System.out.println("already being initialized"); //$NON-NLS-1$
			}
		} else {
			try {
				// if already being re-initialized, we don't want to
				// reset the data in the stateData field.
				model.aboutToChangeModel();
				model.setReinitializeStateData(newLanguage);
				model.setReinitializeNeeded(true);
			} finally {
				model.changedModel();
			}
		}
	}

	public void setCachedLanguage(String newLanguage) {
		if (cachedLanguage != null
				&& languageStateChanged(cachedLanguage, newLanguage)) {
			/*
			 * a complete re-init overkill in current system, since really just
			 * need for the line style providers, BUT, a change in language
			 * could effect other things, and we don't expect to happen often so
			 * a little overkill isn't too bad. The deep problem is that there
			 * is no way to get at the "edit side" adpapters specifically here
			 * in model class. we have to do the model changed sequence to get
			 * the screen to update. do not signal again, if signaled once (the
			 * reinit state data will be wrong. (this needs to be improved in
			 * future)
			 */
			if (!model.isReinitializationNeeded()) {
				modelReinitNeeded(cachedLanguage, newLanguage);
			}
		}
		setLanguage(newLanguage);
	}

	/**
	 * This is public access method, used especially from loader, for JSP
	 * Fragment support.
	 */
	public void setLanguage(String newLanguage) {
		this.cachedLanguage = newLanguage;
		IDocumentPartitioner partitioner = ((IDocumentExtension3) model
				.getStructuredDocument())
				.getDocumentPartitioner(IStructuredPartitioning.DEFAULT_STRUCTURED_PARTITIONING);
		if (partitioner instanceof StructuredTextPartitionerForJSP) {
			((StructuredTextPartitionerForJSP) partitioner)
					.setLanguage(newLanguage);
		}
	}

	/**
	 * Method languageStateChange.
	 * 
	 * @param cachedLanguage
	 * @param newLanguage
	 * @return boolean
	 */
	private boolean languageStateChanged(String cachedLanguage,
			String newLanguage) {
		boolean result = false; // languages are equal, then no change in
		// state
		if (!cachedLanguage.equalsIgnoreCase(newLanguage)) {
			boolean oldLanguageKnown = languageKnown(cachedLanguage);
			boolean newLanguageKnown = languageKnown(newLanguage);
			result = newLanguageKnown
					|| (!newLanguageKnown && oldLanguageKnown);
		}
		return result;
	}

	/**
	 * Method languageKnown.
	 * 
	 * @param cachedLanguage
	 * @return boolean
	 */
	private boolean languageKnown(String language) {
		return (StringUtils.contains(JAVA_LANGUAGE_KEYS, language, false) || StringUtils
				.contains(JAVASCRIPT_LANGUAGE_KEYS, language, false));
	}

	private IFile getFile(IStructuredModel model) {
		String location = model.getBaseLocation();
		if (location != null) {
			IPath path = new Path(location);
			if (path.segmentCount() > 1) {
				return ResourcesPlugin.getWorkspace().getRoot().getFile(path);
			}
		}
		return null;
	}

	private EmbeddedTypeHandler getHandlerFor(String contentType) {
		EmbeddedTypeRegistry reg = getEmbeddedContentTypeRegistry();
		EmbeddedTypeHandler handler = null;
		if (reg != null) {
			handler = reg.getTypeFor(contentType);
		}
		return handler;
	}

	/**
	 * Gets the embeddedContentTypeRegistry.
	 * 
	 * @return Returns a EmbeddedContentTypeRegistry
	 */
	private EmbeddedTypeRegistry getEmbeddedContentTypeRegistry() {
		return EmbeddedTypeRegistryImpl.getInstance();
	}

	/**
	 * For JSP files, text/html is the default content type. This may want this
	 * different for types like jsv (jsp for voice xml) For now, hard code to
	 * new instance. In future, should get instance from registry.
	 * 
	 * Specification cites HTML as the default contentType.
	 */
	protected EmbeddedTypeHandler getDefaultEmbeddedType() {
		return getHandlerFor(getDefaultContentType());
	}

	public INodeNotifier getTarget() {
		return notifierAtCreation;
	}

	public void release() {
		if (embeddedTypeHandler != null) {
			if (embeddedFactoryRegistry != null) {
				Iterator iterator = embeddedFactoryRegistry.iterator();
				INodeAdapterFactory factory = null;
				while (iterator.hasNext()) {
					factory = (INodeAdapterFactory) iterator.next();
					factory.release();
				}
			}
			// pa_TODO: possibly need to release here...
			// or "uninitializeFactoryRegistry"
			// initializeFactoryRegistry was called from JSPModelLoader
			embeddedTypeHandler = null;
		}
	}

	private IContentDescription getContentDescription(IDocument doc) {
		if (doc == null) {
			return null;
		}
		DocumentInputStream in = new DocumentInputStream(doc);
		return getContentDescription(in);
	}

	/**
	 * Returns content description for an input stream Assumes it's JSP content.
	 * Closes the input stream when finished.
	 * 
	 * @param in
	 * @return the IContentDescription for in, or null if in is null
	 */
	private IContentDescription getContentDescription(DocumentInputStream in) {

		if (in == null) {
			return null;
		}

		IContentDescription desc = null;
		try {

			IContentType contentTypeJSP = Platform.getContentTypeManager()
					.getContentType(ContentTypeIdForJSP.ContentTypeID_JSP);
			desc = contentTypeJSP
					.getDescriptionFor(in, IContentDescription.ALL);
		} catch (IOException e) {
			Logger.logException(e);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					Logger.logException(e);
				}
			}
		}
		return desc;
	}
}