/*******************************************************************************
 * 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.jst.jsp.core.internal.contentmodel;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.List;
import java.util.Stack;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.jsp.core.contentmodel.tld.JSP12TLDNames;
import org.eclipse.jst.jsp.core.internal.Logger;
import org.eclipse.jst.jsp.core.internal.util.DocumentProvider;
import org.eclipse.wst.sse.core.util.JarUtilities;
import org.eclipse.wst.xml.uriresolver.util.URIHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

class ProjectDescription {

	class DeltaVisitor implements IResourceDeltaVisitor {
		public boolean visit(IResourceDelta delta) throws CoreException {
			if (delta.getResource().getType() == IResource.FILE) {
				if (delta.getResource().getName().endsWith(".tld")) {
					if (delta.getKind() == IResourceDelta.REMOVED) {
						removeTLD(delta.getResource());
					}
					else {
						addTLD(delta.getResource());
					}
				}
				else if (delta.getResource().getName().endsWith(".jar")) {
					if (delta.getKind() == IResourceDelta.REMOVED) {
						removeJAR(delta.getResource());
					}
					else {
						addJAR(delta.getResource());
					}
				}
				else if (delta.getResource().getName().endsWith(".tag") || delta.getResource().getName().endsWith(".tagx")) {
					if (delta.getKind() == IResourceDelta.REMOVED) {
						removeTagDir(delta.getResource());
					}
					else {
						addTagDir(delta.getResource());
					}
				}
				else if (delta.getResource().getName().equals(WEB_XML) && delta.getResource().getParent().getName().equals(WEB_INF)) {
					if (delta.getKind() == IResourceDelta.REMOVED) {
						removeServlets(delta.getResource());
					}
					else {
						addServlets(delta.getResource());
					}
				}
			}
			return true;
		}
	}

	class Indexer implements IResourceProxyVisitor {
		public boolean visit(IResourceProxy proxy) throws CoreException {
			if (proxy.getType() == IResource.FILE) {
				if (proxy.getName().endsWith(".tld")) {
					addTLD(proxy.requestResource());
				}
				else if (proxy.getName().endsWith(".jar")) {
					addJAR(proxy.requestResource());
				}
				else if (proxy.getName().endsWith(".tag") || proxy.getName().endsWith(".tagx")) {
					addTagDir(proxy.requestResource());
				}
				else if (proxy.getName().equals(WEB_XML) && proxy.requestResource().getParent().getName().equals(WEB_INF)) {
					addServlets(proxy.requestResource());
				}
			}
			return true;
		}
	}

	class TaglibRecordEvent implements ITaglibRecordEvent {
		ITaglibRecord fTaglibRecord = null;
		short fType = -1;

		TaglibRecordEvent(ITaglibRecord record, short type) {
			fTaglibRecord = record;
			fType = type;
		}

		public ITaglibRecord getTaglibRecord() {
			return fTaglibRecord;
		}

		public short getType() {
			return fType;
		}
	}

	static boolean _debugIndexCreation = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jst.jsp.core/taglib/indexcreation"));
	static boolean _debugIndexTime = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jst.jsp.core/taglib/indextime"));

	private static final String WEB_INF = "WEB-INF";

	private static final IPath WEB_INF_PATH = new Path("WEB-INF");
	private static final String WEB_XML = "web.xml";

	/*
	 * Records active JARs on the classpath. Taglib descriptors should be
	 * usable, but the jars by themselves should not.
	 */
	Hashtable fClasspathJars;

	// holds references by URI to TLDs
	Hashtable fClasspathReferences;

	// this table is special in that it holds tables of references according
	// to local roots
	Hashtable fImplicitReferences;
	Hashtable fJARReferences;
	IProject fProject;

	Stack fProjectStack = null;
	Hashtable fServletReferences;
	Hashtable fTagDirReferences;

	Hashtable fTLDReferences;

	IResourceDeltaVisitor fVisitor;

	private long time0;

	ProjectDescription(IProject project) {
		super();
		fProject = project;
		fClasspathReferences = new Hashtable(0);
		fClasspathJars = new Hashtable(0);
		fJARReferences = new Hashtable(0);
		fTagDirReferences = new Hashtable(0);
		fTLDReferences = new Hashtable(0);
		fServletReferences = new Hashtable(0);
		fImplicitReferences = new Hashtable(0);
	}

	void addClasspathLibrary(String libraryLocation) {
		String[] entries = JarUtilities.getEntryNames(libraryLocation);
		JarRecord libraryRecord = (JarRecord) createJARRecord(libraryLocation);
		fClasspathJars.put(libraryLocation, libraryRecord);
		for (int i = 0; i < entries.length; i++) {
			if (entries[i].endsWith(".tld")) {
				InputStream contents = JarUtilities.getInputStream(libraryLocation, entries[i]);
				if (contents != null) {
					String uri = extractURI(libraryLocation, contents);
					if (uri != null && uri.length() > 0) {
						URLRecord record = new URLRecord();
						record.uri = uri;
						record.baseLocation = libraryLocation;
						try {
							record.url = new URL("jar:file:" + libraryLocation + "!/" + entries[i]);
							libraryRecord.urlRecords.add(record);
							fClasspathReferences.put(uri, record);
							if (_debugIndexCreation)
								System.out.println("created record for " + uri + "@" + record.getURL());
						}
						catch (MalformedURLException e) {
							// don't record this URI
							Logger.logException(e);
						}
					}
					try {
						contents.close();
					}
					catch (IOException e) {
					}
				}
			}
		}
		TaglibIndex.fireTaglibRecordEvent(new TaglibRecordEvent(libraryRecord, ITaglibRecordEvent.ADD));
	}

	void addJAR(IResource jar) {
		if (_debugIndexCreation)
			System.out.println("creating records for JAR " + jar.getFullPath());
		String jarLocationString = jar.getLocation().toString();
		String[] entries = JarUtilities.getEntryNames(jar);
		JarRecord jarRecord = (JarRecord) createJARRecord(jar);
		fJARReferences.put(jar.getFullPath().toString(), jarRecord);
		for (int i = 0; i < entries.length; i++) {
			if (entries[i].endsWith(".tld")) {
				InputStream contents = JarUtilities.getInputStream(jar, entries[i]);
				if (contents != null) {
					String uri = extractURI(jarLocationString, contents);
					if (uri != null && uri.length() > 0) {
						URLRecord record = new URLRecord();
						record.uri = uri;
						record.baseLocation = jarLocationString;
						try {
							record.url = new URL("jar:file:" + jarLocationString + "!/" + entries[i]);
							jarRecord.urlRecords.add(record);
							getImplicitReferences(jarLocationString).put(uri, record);
							if (_debugIndexCreation)
								System.out.println("created record for " + uri + "@" + record.getURL());
						}
						catch (MalformedURLException e) {
							// don't record this URI
							Logger.logException(e);
						}
					}
					try {
						contents.close();
					}
					catch (IOException e) {
					}
				}
			}
		}
		TaglibIndex.fireTaglibRecordEvent(new TaglibRecordEvent(jarRecord, ITaglibRecordEvent.ADD));
	}

	void addServlets(IResource webxml) {
		if (webxml.getType() != IResource.FILE)
			return;
		InputStream webxmlContents = null;
		Document document = null;
		try {
			webxmlContents = ((IFile) webxml).getContents(true);
			DocumentProvider provider = new DocumentProvider();
			provider.setInputStream(webxmlContents);
			provider.setValidating(false);
			provider.setBaseReference(webxml.getParent().getLocation().toString());
			document = provider.getDocument();
		}
		catch (CoreException e) {
			Logger.logException(e);
		}
		finally {
			if (webxmlContents != null)
				try {
					webxmlContents.close();
				}
				catch (IOException e1) {
					// ignore
				}
		}
		if (document == null)
			return;
		if (_debugIndexCreation)
			System.out.println("creating records for " + webxml.getFullPath());

		ServletRecord servletRecord = new ServletRecord();
		servletRecord.location = webxml.getLocation();
		fServletReferences.put(servletRecord.getWebXML().toString(), servletRecord);
		NodeList taglibs = document.getElementsByTagName(JSP12TLDNames.TAGLIB);
		for (int i = 0; i < taglibs.getLength(); i++) {
			String uri = readTextofChild(taglibs.item(i), "taglib-uri");
			// specified location is relative to root of the webapp
			String location = readTextofChild(taglibs.item(i), "taglib-location");
			TLDRecord record = new TLDRecord();
			record.uri = uri;
			if (location.startsWith("/")) {
				record.location = ResourcesPlugin.getWorkspace().getRoot().getLocation().append(getLocalRoot(webxml.getLocation().toString()) + location);
			}
			else {
				record.location = new Path(URIHelper.normalize(location, webxml.getLocation().toString(), getLocalRoot(webxml.getLocation().toString())));
			}
			servletRecord.tldRecords.add(record);
			getImplicitReferences(webxml.getLocation().toString()).put(uri, record);
			if (_debugIndexCreation)
				System.out.println("created record for " + uri + "@" + record.location);
		}
		TaglibIndex.fireTaglibRecordEvent(new TaglibRecordEvent(servletRecord, ITaglibRecordEvent.ADD));
	}

	void addTagDir(IResource tagFile) {
		return;
		/**
		 * Make sure the tag file is n a WEB-INF/tags folder because of the
		 * shortname computation requirements
		 */
		// if ((tagFile.getType() & IResource.FOLDER) > 0 ||
		// tagFile.getFullPath().toString().indexOf("WEB-INF/tags") < 0)
		// return;
		// TagDirRecord record = createTagdirRecord(tagFile);
		// if (record != null) {
		// record.tags.add(tagFile.getName());
		// }
	}

	void addTLD(IResource tld) {
		if (_debugIndexCreation)
			System.out.println("creating record for " + tld.getFullPath());
		TLDRecord record = createTLDRecord(tld);
		fTLDReferences.put(tld.getFullPath().toString(), record);
		if (record.uri != null) {
			getImplicitReferences(tld.getLocation().toString()).put(record.uri, record);
		}
		TaglibIndex.fireTaglibRecordEvent(new TaglibRecordEvent(record, ITaglibRecordEvent.ADD));
	}

	void clear() {
	}

	/**
	 * @param resource
	 * @return
	 */
	private ITaglibRecord createJARRecord(IResource jar) {
		return createJARRecord(jar.getLocation().toString());
	}

	private ITaglibRecord createJARRecord(String fileLocation) {
		JarRecord record = new JarRecord();
		record.location = new Path(fileLocation);
		record.urlRecords = new ArrayList(0);
		return record;
	}

	/**
	 * @return
	 */
	TagDirRecord createTagdirRecord(IResource tagFile) {
		IContainer tagdir = tagFile.getParent();
		String tagdirLocation = tagdir.getFullPath().toString();
		TagDirRecord record = (TagDirRecord) fTagDirReferences.get(tagdirLocation);
		if (record == null) {
			record = new TagDirRecord();
			record.location = tagdir.getFullPath();
			// JSP 2.0 section 8.4.3
			if (tagdir.getName().equals("tags"))
				record.shortName = "tags";
			else {
				IPath tagdirPath = tagdir.getFullPath();
				String[] segments = tagdirPath.segments();
				for (int i = 1; record.shortName == null && i < segments.length; i++) {
					if (segments[i - 1].equals("WEB-INF") && segments[i].equals("tags")) {
						IPath tagdirLocalPath = tagdirPath.removeFirstSegments(i + 1);
						record.shortName = tagdirLocalPath.toString().replace('/', '-');
					}
				}
			}

		}
		return record;
	}

	/**
	 * @param resource
	 * @return
	 */
	private TLDRecord createTLDRecord(IResource tld) {
		TLDRecord record = new TLDRecord();
		record.location = tld.getLocation();
		InputStream contents = null;
		try {
			contents = ((IFile) tld).getContents(true);
			String baseLocation = record.location.toString();
			String defaultURI = extractURI(baseLocation, contents);
			if (defaultURI != null && defaultURI.length() > 0) {
				record.uri = defaultURI;
			}
		}
		catch (CoreException e) {
			Logger.logException(e);
		}
		finally {
			try {
				if (contents != null) {
					contents.close();
				}
			}
			catch (IOException e) {
				// ignore
			}
		}
		return record;
	}

	/**
	 * @param tldContents
	 * @return
	 */
	private String extractURI(String baseLocation, InputStream tldContents) {
		StringBuffer uri = new StringBuffer();
		Node result = null;
		DocumentProvider provider = new DocumentProvider();
		provider.setInputStream(tldContents);
		provider.setValidating(false);
		provider.setRootElementName(JSP12TLDNames.TAGLIB);
		provider.setBaseReference(baseLocation);
		result = provider.getRootElement();
		if (result.getNodeType() != Node.ELEMENT_NODE)
			return null;
		Element taglibElement = (Element) result;
		if (taglibElement != null) {
			Node child = taglibElement.getFirstChild();
			while (child != null && !(child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals(JSP12TLDNames.URI))) {
				child = child.getNextSibling();
			}
			if (child != null) {
				Node text = child.getFirstChild();
				while (text != null) {
					if (text.getNodeType() == Node.TEXT_NODE || text.getNodeType() == Node.CDATA_SECTION_NODE) {
						uri.append(text.getNodeValue().trim());
					}
					text = text.getNextSibling();
				}
			}
		}
		return uri.toString();
	}

	synchronized List getAvailableTaglibRecords(IPath location) {
		Collection implicitReferences = getImplicitReferences(location.toString()).values();
		List records = new ArrayList(fTLDReferences.size() + fTagDirReferences.size() + fJARReferences.size() + fServletReferences.size());
		records.addAll(fTLDReferences.values());
		records.addAll(fTagDirReferences.values());
		records.addAll(fJARReferences.values());
		records.addAll(fServletReferences.values());
		records.addAll(implicitReferences);
		return records;
	}

	/**
	 * @return Returns the implicitReferences for the given path
	 */
	Hashtable getImplicitReferences(String location) {
		String localRoot = getLocalRoot(location);
		Hashtable implicitReferences = (Hashtable) fImplicitReferences.get(localRoot);
		if (implicitReferences == null) {
			implicitReferences = new Hashtable(1);
			fImplicitReferences.put(localRoot, implicitReferences);
		}
		return implicitReferences;
	}

	/**
	 * @param baseLocation
	 * @return the applicable Web context root path, if one exists
	 */
	IPath getLocalRoot(IPath baseLocation) {
		IResource file = FileBuffers.getWorkspaceFileAtLocation(baseLocation);
		while (file != null) {
			/**
			 * Treat any parent folder with a WEB-INF subfolder as a web-app
			 * root
			 */
			IContainer folder = null;
			if ((file.getType() & IResource.FOLDER) != 0) {
				folder = (IContainer) file;
			}
			else {
				folder = file.getParent();
			}
			// getFolder on a workspace root must use a full path, skip
			if (folder != null && (folder.getType() & IResource.ROOT) == 0) {
				IFolder webinf = folder.getFolder(WEB_INF_PATH);
				if (webinf != null && webinf.exists()) {
					return folder.getFullPath();
				}
			}
			file = file.getParent();
		}

		return fProject.getFullPath();
	}

	/**
	 * @param baseLocation
	 * @return
	 */
	private String getLocalRoot(String baseLocation) {
		return getLocalRoot(new Path(baseLocation)).toString();
	}

	/**
	 * @return Returns the visitor.
	 */
	IResourceDeltaVisitor getVisitor() {
		if (fVisitor == null) {
			fVisitor = new DeltaVisitor();
		}
		return fVisitor;
	}

	void index() {
		time0 = System.currentTimeMillis();
		fTLDReferences.clear();
		fJARReferences.clear();
		fTagDirReferences.clear();
		fServletReferences.clear();
		try {
			fProject.accept(new Indexer(), 0);
		}
		catch (CoreException e) {
			Logger.logException(e);
		}

		if (_debugIndexTime)
			System.out.println("indexed " + fProject.getName() + " in " + (System.currentTimeMillis() - time0) + "ms");
	}

	void indexClasspath() {
		time0 = System.currentTimeMillis();
		fProjectStack = new Stack();
		fClasspathReferences.clear();
		IJavaProject javaProject = JavaCore.create(fProject);
		indexClasspath(javaProject);
		if (_debugIndexTime)
			System.out.println("indexed " + fProject.getName() + " classpath in " + (System.currentTimeMillis() - time0) + "ms");
	}

	/**
	 * @param javaProject
	 */
	private void indexClasspath(IJavaProject javaProject) {
		if (javaProject != null && javaProject.exists()) {
			fProjectStack.push(javaProject.getElementName());
			try {
				IClasspathEntry[] entries = javaProject.getResolvedClasspath(true);
				for (int i = 0; i < entries.length; i++) {
					IClasspathEntry entry = entries[i];
					switch (entry.getEntryKind()) {
						case IClasspathEntry.CPE_CONTAINER :
							break;
						case IClasspathEntry.CPE_LIBRARY : {
							/*
							 * Ignore libs in required projects that are not
							 * exported
							 */
							if (fProjectStack.size() < 2 || entry.isExported()) {
								IPath libPath = entry.getPath();
								if (libPath.toFile().exists()) {
									addClasspathLibrary(libPath.toString());
								}
								else {
									IFile libFile = ResourcesPlugin.getWorkspace().getRoot().getFile(libPath);
									if (libFile != null && libFile.exists()) {
										addClasspathLibrary(libFile.getLocation().toString());
									}
								}
							}
						}
							break;
						case IClasspathEntry.CPE_PROJECT : {
							/*
							 * Ignore required projects of required projects
							 * that are not exported
							 */
							if (fProjectStack.size() < 2 || entry.isExported()) {
								IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(entry.getPath().lastSegment());
								if (project != null && !fProjectStack.contains(project.getName())) {
									indexClasspath(JavaCore.create(project));
								}
							}
						}
							break;
						case IClasspathEntry.CPE_SOURCE :
							break;
						case IClasspathEntry.CPE_VARIABLE :
							break;
					}
				}
			}
			catch (JavaModelException e) {
				Logger.logException("Error searching Java Build Path + (" + fProject.getName() + ") for tag libraries", e);
			}
			fProjectStack.pop();
		}
	}

	protected String readTextofChild(Node node, String childName) {
		StringBuffer buffer = new StringBuffer();
		NodeList children = node.getChildNodes();
		for (int i = 0; i < children.getLength(); i++) {
			Node child = children.item(i);
			if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals(childName)) {
				Node text = child.getFirstChild();
				while (text != null) {
					buffer.append(text.getNodeValue().trim());
					text = text.getNextSibling();
				}
			}
		}
		return buffer.toString();
	}

	void removeClasspathLibrary(String libraryLocation) {
		JarRecord record = (JarRecord) fClasspathJars.remove(libraryLocation);
		if (record != null) {
			URLRecord[] records = (URLRecord[]) record.getURLRecords().toArray(new URLRecord[0]);
			for (int i = 0; i < records.length; i++) {
				fClasspathReferences.remove(records[i].getURI());
			}
			TaglibIndex.fireTaglibRecordEvent(new TaglibRecordEvent(record, ITaglibRecordEvent.REMOVE));
		}
	}

	void removeJAR(IResource jar) {
		if (_debugIndexCreation)
			System.out.println("removing records for JAR " + jar.getFullPath());
		JarRecord record = (JarRecord) fJARReferences.remove(jar.getFullPath());
		if (record != null) {
			URLRecord[] records = (URLRecord[]) record.getURLRecords().toArray(new URLRecord[0]);
			for (int i = 0; i < records.length; i++) {
				getImplicitReferences(jar.getLocation().toString()).remove(records[i].getURI());
			}
			TaglibIndex.fireTaglibRecordEvent(new TaglibRecordEvent(record, ITaglibRecordEvent.REMOVE));
		}
	}

	void removeServlets(IResource webxml) {
		if (_debugIndexCreation)
			System.out.println("removing records for " + webxml.getFullPath());
		ServletRecord record = (ServletRecord) fServletReferences.remove(webxml.getLocation().toString());
		if (record != null) {
			TLDRecord[] records = (TLDRecord[]) record.getTLDRecords().toArray(new TLDRecord[0]);
			for (int i = 0; i < records.length; i++) {
				if (_debugIndexCreation)
					System.out.println("removed record for " + records[i].uri + "@" + records[i].location);
				getImplicitReferences(webxml.getLocation().toString()).remove(records[i].getURI());
			}
			TaglibIndex.fireTaglibRecordEvent(new TaglibRecordEvent(record, ITaglibRecordEvent.REMOVE));
		}
	}

	void removeTagDir(IResource tagFile) {
		// IContainer tagdir = tagFile.getParent();
		// String tagdirLocation = tagdir.getFullPath().toString();
		// fTagDirReferences.remove(tagdirLocation);
	}

	void removeTLD(IResource tld) {
		if (_debugIndexCreation)
			System.out.println("removing record for " + tld.getFullPath());
		TLDRecord record = (TLDRecord) fTLDReferences.remove(tld.getFullPath());
		if (record != null) {
			if (record.uri != null) {
				getImplicitReferences(tld.getLocation().toString()).remove(record.uri);
			}
			TaglibIndex.fireTaglibRecordEvent(new TaglibRecordEvent(record, ITaglibRecordEvent.REMOVE));
		}
	}

	/**
	 * @param basePath
	 * @param reference
	 * @return
	 */
	ITaglibRecord resolve(String basePath, String reference) {
		ITaglibRecord record = null;
		String location = null;

		/**
		 * Workaround for problem in URIHelper; uris starting with '/' are
		 * returned as-is.
		 */
		if (reference.startsWith("/")) {
			location = getLocalRoot(basePath) + reference;
		}
		else {
			location = URIHelper.normalize(reference, basePath, getLocalRoot(basePath));
		}
		// order dictated by JSP spec 2.0 section 7.2.3
		if (record == null) {
			record = (ITaglibRecord) fServletReferences.get(location);
		}
		if (record == null) {
			record = (ITaglibRecord) fJARReferences.get(location);
		}
		if (record == null) {
			record = (ITaglibRecord) fTLDReferences.get(location);
		}
		if (record == null) {
			record = (ITaglibRecord) getImplicitReferences(basePath).get(reference);
		}
		if (record == null) {
			record = (ITaglibRecord) fTagDirReferences.get(location);
		}
		if (record == null) {
			record = (ITaglibRecord) fClasspathReferences.get(reference);
		}
		return record;
	}
}
