/*******************************************************************************
 * 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.core.internal.java.search;

import java.io.File;
import java.util.zip.CRC32;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.wst.jsdt.core.IJavaElement;
import org.eclipse.wst.jsdt.core.search.IJavaSearchConstants;
import org.eclipse.wst.jsdt.core.search.IJavaSearchScope;
import org.eclipse.wst.jsdt.core.search.SearchDocument;
import org.eclipse.wst.jsdt.core.search.SearchEngine;
import org.eclipse.wst.jsdt.core.search.SearchPattern;
import org.eclipse.wst.jsdt.core.search.SearchRequestor;
import org.eclipse.wst.jsdt.internal.core.JavaModelManager;
import org.eclipse.wst.jsdt.web.core.internal.JSPCoreMessages;
import org.eclipse.wst.jsdt.web.core.internal.JSPCorePlugin;
import org.eclipse.wst.jsdt.web.core.internal.Logger;
import org.eclipse.wst.jsdt.web.core.internal.java.JSP2ServletNameUtil;
import org.eclipse.wst.jsdt.web.core.internal.provisional.contenttype.ContentTypeIdForJSP;

/**
 * Central access to java indexing and search. All contact between JDT indexing
 * and Searching should be done through here.
 * 
 * Clients should access the methods of this class via the single instance via
 * <code>getInstance()</code>.
 * 
 * @author pavery
 */
public class JSPSearchSupport {

	// for debugging
	static final boolean DEBUG;
	static {
		String value = Platform
				.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jspsearch"); //$NON-NLS-1$
		DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
	}

	private static JSPSearchSupport singleton = null;

	private JSPSearchParticipant fParticipant = null;

	private IPath fJspPluginLocation = null;

	// pa_TODO may be slow (esp for indexing entire workspace)
	private final CRC32 fChecksumCalculator = new CRC32();

	/** main cancel montior for all search support */
	private final IProgressMonitor fMonitor = new NullProgressMonitor();

	private JSPSearchSupport() {
		// force use of single instance
	}

	/**
	 * This operation ensures that the live resource's search markers show up in
	 * the open editor. It also allows the ability to pass in a ProgressMonitor
	 */
	private class SearchJob extends Job implements IJavaSearchConstants {

		String fSearchText = ""; //$NON-NLS-1$

		IJavaSearchScope fScope = null;

		int fSearchFor = FIELD;

		int fLimitTo = ALL_OCCURRENCES;

		int fMatchMode = SearchPattern.R_PATTERN_MATCH;

		boolean fIsCaseSensitive = false;

		SearchRequestor fRequestor = null;

		IJavaElement fElement = null;

		// constructor w/ java element
		public SearchJob(IJavaElement element, IJavaSearchScope scope,
				SearchRequestor requestor) {

			super(JSPCoreMessages.JSP_Search + element.getElementName());
			this.fElement = element;
			this.fScope = scope;
			this.fRequestor = requestor;
		}

		// constructor w/ search text
		public SearchJob(String searchText, IJavaSearchScope scope,
				int searchFor, int limitTo, int matchMode,
				boolean isCaseSensitive, SearchRequestor requestor) {

			super(JSPCoreMessages.JSP_Search + searchText);
			this.fSearchText = searchText;
			this.fScope = scope;
			this.fSearchFor = searchFor;
			this.fLimitTo = limitTo;
			this.fMatchMode = matchMode;
			this.fIsCaseSensitive = isCaseSensitive;
			this.fRequestor = requestor;
		}

		@Override
		public IStatus run(IProgressMonitor jobMonitor) {

			if (jobMonitor != null && jobMonitor.isCanceled()) {
				return Status.CANCEL_STATUS;
			}
			if (JSPSearchSupport.getInstance().isCanceled()) {
				return Status.CANCEL_STATUS;
			}

			SearchPattern javaSearchPattern = null;
			// if an element is available, use that to create search pattern
			// (eg. LocalVariable)
			// otherwise use the text and other paramters
			if (this.fElement != null) {
				javaSearchPattern = SearchPattern.createPattern(this.fElement,
						this.fLimitTo);
			} else {
				javaSearchPattern = SearchPattern.createPattern(
						this.fSearchText, this.fSearchFor, this.fLimitTo,
						this.fMatchMode);
			}

			if (javaSearchPattern != null) {
				JSPSearchParticipant[] participants = { getSearchParticipant() };
				SearchEngine engine = new SearchEngine();
				try {
					if (jobMonitor != null) {
						jobMonitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$
					}
					engine.search(javaSearchPattern, participants, this.fScope,
							this.fRequestor, jobMonitor);
				} catch (CoreException e) {
					if (DEBUG) {
						Logger.logException(e);
					}
				}
				// non-CoreExceptions will permanently stall the Worker thread
				catch (Exception e) {
					if (DEBUG) {
						Logger.logException(e);
					}
				} finally {
					if (jobMonitor != null) {
						jobMonitor.done();
					}
				}
			}
			return Status.OK_STATUS;
		}
	}

	// end SearchJob
	/**
	 * Runnable forces caller to wait until finished (as opposed to using a Job)
	 */
	private class SearchRunnable implements IWorkspaceRunnable,
			IJavaSearchConstants {

		String fSearchText = ""; //$NON-NLS-1$

		IJavaSearchScope fScope = null;

		int fSearchFor = FIELD;

		int fLimitTo = ALL_OCCURRENCES;

		int fMatchMode = SearchPattern.R_PATTERN_MATCH;

		boolean fIsCaseSensitive = false;

		SearchRequestor fRequestor = null;

		IJavaElement fElement = null;

		// constructor w/ java element
		public SearchRunnable(IJavaElement element, IJavaSearchScope scope,
				SearchRequestor requestor) {

			this.fElement = element;
			this.fScope = scope;
			this.fRequestor = requestor;
		}

		// constructor w/ search text
		public SearchRunnable(String searchText, IJavaSearchScope scope,
				int searchFor, int limitTo, int matchMode,
				boolean isCaseSensitive, SearchRequestor requestor) {

			this.fSearchText = searchText;
			this.fScope = scope;
			this.fSearchFor = searchFor;
			this.fLimitTo = limitTo;
			this.fMatchMode = matchMode;
			this.fIsCaseSensitive = isCaseSensitive;
			this.fRequestor = requestor;
		}

		public void run(IProgressMonitor monitor) throws CoreException {

			if (monitor != null && monitor.isCanceled()) {
				return;
			}
			if (JSPSearchSupport.getInstance().isCanceled()) {
				return;
			}

			SearchPattern javaSearchPattern = null;
			// if an element is available, use that to create search pattern
			// (eg. LocalVariable)
			// otherwise use the text and other paramters
			if (this.fElement != null) {
				javaSearchPattern = SearchPattern.createPattern(this.fElement,
						fLimitTo);
			} else {
				javaSearchPattern = SearchPattern.createPattern(fSearchText,
						fSearchFor, fLimitTo, fMatchMode);
			}

			if (javaSearchPattern != null) {
				JSPSearchParticipant[] participants = { getSearchParticipant() };
				SearchEngine engine = new SearchEngine();
				try {
					if (monitor != null) {
						monitor.beginTask("", 0); //$NON-NLS-1$
					}
					engine.search(javaSearchPattern, participants, fScope,
							fRequestor, monitor);
				} catch (CoreException e) {
					Logger.logException(e);
					// throw e;
				}
				// non-CoreExceptions will permanently stall the Worker thread
				catch (Exception e) {
					Logger.logException(e);
				} finally {
					if (monitor != null) {
						monitor.done();
					}
				}
			}
		}
	}

	// end SearchRunnable

	/**
	 * Clients should access the methods of this class via the single instance
	 * via getInstance()
	 * 
	 * @return
	 */
	public synchronized static JSPSearchSupport getInstance() {

		if (singleton == null) {
			singleton = new JSPSearchSupport();
		}
		return singleton;
	}

	/**
	 * Utility method to check if a file is a jsp file (since this is done
	 * frequently)
	 */
	public static boolean isJsp(IFile file) {
		// (pa) 20051025 removing deep content type check
		// because this method is called frequently
		// and IO is expensive
		boolean isJsp = false;

		if (file != null && file.exists()) {

			IContentType contentTypeJSP = Platform.getContentTypeManager()
					.getContentType(ContentTypeIdForJSP.ContentTypeID_JSP);
			// check this before description, it's less expensive
			if (contentTypeJSP.isAssociatedWith(file.getName())) {
				isJsp = true;
			}
		}

		return isJsp;
	}

	/**
	 * schedules a search document representing this JSP file for indexing (by
	 * the java indexer)
	 * 
	 * @param file
	 *            the JSP file
	 * @return true if indexing was successful, false otherwise
	 * @throws CoreException
	 */
	public SearchDocument addJspFile(IFile file) {
		if (JSPSearchSupport.getInstance().isCanceled() || !file.isAccessible()) {
			return null;
		}

		if (DEBUG) {
			System.out.println("adding JSP file:" + file.getFullPath()); //$NON-NLS-1$
		}

		// create
		SearchDocument delegate = createSearchDocument(file);
		// null if not a jsp file
		if (delegate != null) {
			try {
				getSearchParticipant().scheduleDocumentIndexing(delegate,
						computeIndexLocation(file.getParent().getFullPath()));
			} catch (Exception e) {
				// ensure that failure here doesn't keep other documents from
				// being indexed
				// if peformed in a batch call (like JSPIndexManager)
				if (DEBUG) {
					e.printStackTrace();
				}
			}
		}

		if (DEBUG) {
			System.out.println("scheduled" + delegate + "for indexing"); //$NON-NLS-1$ //$NON-NLS-2$
		}

		return delegate;
	}

	/**
	 * Perform a java search w/ the given parameters. Runs in a background Job
	 * (results may still come in after this method call)
	 * 
	 * @param searchText
	 *            the string of text to search on
	 * @param searchFor
	 *            IJavaSearchConstants.TYPE, METHOD, FIELD, PACKAGE, etc...
	 * @param limitTo
	 *            IJavaSearchConstants.DECLARATIONS,
	 *            IJavaSearchConstants.REFERENCES,
	 *            IJavaSearchConstants.IMPLEMENTORS, or
	 *            IJavaSearchConstants.ALL_OCCURRENCES
	 * @param matchMode
	 *            allow * wildcards or not
	 * @param isCaseSensitive
	 * @param requestor
	 *            passed in to accept search matches (and do "something" with
	 *            them)
	 */
	public void search(String searchText, IJavaSearchScope scope,
			int searchFor, int limitTo, int matchMode, boolean isCaseSensitive,
			SearchRequestor requestor) {

		JSPIndexManager.getInstance().rebuildIndexIfNeeded();

		SearchJob job = new SearchJob(searchText, scope, searchFor, limitTo,
				matchMode, isCaseSensitive, requestor);
		setCanceled(false);
		job.setUser(true);
		// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=5032
		// pops up user operation blocked dialog if you perform a long search,
		// then open a file because it locks the workspace
		// job.setRule(ResourcesPlugin.getWorkspace().getRoot());
		job.schedule();
	}

	/**
	 * Search for an IJavaElement, constrained by the given parameters. Runs in
	 * a background Job (results may still come in after this method call)
	 * 
	 * @param element
	 * @param scope
	 * @param requestor
	 */
	public void search(IJavaElement element, IJavaSearchScope scope,
			SearchRequestor requestor) {

		JSPIndexManager.getInstance().rebuildIndexIfNeeded();

		SearchJob job = new SearchJob(element, scope, requestor);
		setCanceled(false);
		job.setUser(true);
		// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=5032
		// job.setRule(ResourcesPlugin.getWorkspace().getRoot());
		job.schedule();
	}

	/**
	 * Search for an IJavaElement, constrained by the given parameters. Runs in
	 * an IWorkspace runnable (results will be reported by the end of this
	 * method)
	 * 
	 * @param element
	 * @param scope
	 * @param requestor
	 */
	public void searchRunnable(IJavaElement element, IJavaSearchScope scope,
			SearchRequestor requestor) {

		JSPIndexManager.getInstance().rebuildIndexIfNeeded();

		SearchRunnable searchRunnable = new SearchRunnable(element, scope,
				requestor);
		try {
			setCanceled(false);
			ResourcesPlugin.getWorkspace().run(searchRunnable,
					JSPSearchSupport.getInstance().getProgressMonitor());
		} catch (CoreException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @param jspFile
	 * @return SearchDocument if the file is not null, exists, and is a JSP
	 *         file, otherwise null.
	 */
	private SearchDocument createSearchDocument(IFile jspFile) {

		JavaSearchDocumentDelegate delegate = null;
		if (jspFile != null && jspFile.exists() && isJsp(jspFile)) {

			delegate = new JavaSearchDocumentDelegate(new JSPSearchDocument(
					jspFile.getFullPath().toString(), getSearchParticipant()));
		}
		return delegate;

	}

	/**
	 * Centralized place to access JSPSearchDocuments (used by
	 * JSPSearchParticipant and JSPSearchRequestor)
	 * 
	 * @param searchDocPath
	 * @param doc
	 * @return the JSPSearchDocument or null if one is not found
	 */
	public SearchDocument getSearchDocument(String searchDocPath) {

		SearchDocument delegate = null;
		IFile f = fileForCUPath(searchDocPath);
		if (f != null) {
			delegate = createSearchDocument(f);
		} else {
			// handle failure case... (file deleted maybe?)
		}
		return delegate;
	}

	/**
	 * Unmangles the searchDocPath and returns the corresponding JSP file.
	 * 
	 * @param searchDocPath
	 */
	private IFile fileForCUPath(String searchDocPath) {

		String[] split = searchDocPath.split("/"); //$NON-NLS-1$
		String classname = split[split.length - 1];

		// ignore anything but .java matches (like .class binary matches)
		if (!searchDocPath.endsWith(".java")) { //$NON-NLS-1$
			return null;
		}

		String filePath = JSP2ServletNameUtil.unmangle(classname);

		// try absolute path
		IFile f = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(
				new Path(filePath));
		// workspace relative then
		if (f == null) {
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=86009
			// must have a project name as well
			// which would mean >= 2 path segments
			IPath path = new Path(filePath);
			if (path.segmentCount() >= 2) {
				f = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
			}
		}
		return f;
	}

	JSPSearchParticipant getSearchParticipant() {

		if (this.fParticipant == null) {
			this.fParticipant = new JSPSearchParticipant();
		}
		return this.fParticipant;
	}

	// This is called from JSPPathIndexer
	// pa_TODO
	// how can we make sure participant indexLocations are updated at startup?
	public final IPath computeIndexLocation(IPath containerPath) {

		String indexLocation = null;
		// we don't want to inadvertently use a JDT Index
		// we want to be sure to use the Index from the JSP location
		// Object obj = indexLocations.get(containerPath);
		// if (obj != null) {
		// indexLocation = (String) obj;
		// } else {
		// create index entry
		String pathString = containerPath.toOSString();
		this.fChecksumCalculator.reset();
		this.fChecksumCalculator.update(pathString.getBytes());
		String fileName = Long.toString(this.fChecksumCalculator.getValue())
				+ ".index"; //$NON-NLS-1$
		// this is the only difference from
		// IndexManager#computeIndexLocation(...)
		indexLocation = getModelJspPluginWorkingLocation().append(fileName)
				.toOSString();

		// pa_TODO need to add to java path too, so JDT search support knows
		// there should be a non internal way to do this.
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=77564
		JavaModelManager.getJavaModelManager().getIndexManager().indexLocations
				.put(containerPath, indexLocation);
		// }
		return new Path(indexLocation);
	}

	// copied from JDT IndexManager
	public IPath getModelJspPluginWorkingLocation() {

		if (this.fJspPluginLocation != null) {
			return this.fJspPluginLocation;
		}

		// Append the folder name "jspsearch" to keep the state location area
		// cleaner
		IPath stateLocation = JSPCorePlugin.getDefault().getStateLocation()
				.append("jspsearch");

		// pa_TODO workaround for
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=62267
		// copied from IndexManager
		String device = stateLocation.getDevice();
		if (device != null && device.charAt(0) == '/') {
			stateLocation = stateLocation.setDevice(device.substring(1));
		}

		// ensure that it exists on disk
		File folder = new File(stateLocation.toOSString());
		if (!folder.isDirectory()) {
			try {
				folder.mkdir();
			} catch (SecurityException e) {
			}
		}

		return this.fJspPluginLocation = stateLocation;
	}

	/**
	 * JSP Indexing and Search jobs check this
	 * 
	 * @return
	 */
	public synchronized final void setCanceled(boolean cancel) {
		// System.out.println("search support monitor" + fMonitor);
		fMonitor.setCanceled(cancel);
	}

	/**
	 * JSP Indexing and Search jobs check this
	 * 
	 * @return
	 */
	public synchronized final boolean isCanceled() {

		return fMonitor.isCanceled();
	}

	/**
	 * JSP Indexing and Search jobs check this
	 * 
	 * @return
	 */
	public final IProgressMonitor getProgressMonitor() {

		return this.fMonitor;
	}
}