/*******************************************************************************
 * 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 {
	
	/**
	 * 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 {
		
		IJavaElement	 fElement		 = null;
		
		boolean		  fIsCaseSensitive = false;
		
		int			  fLimitTo		 = IJavaSearchConstants.ALL_OCCURRENCES;
		
		int			  fMatchMode	   = SearchPattern.R_PATTERN_MATCH;
		
		SearchRequestor  fRequestor	   = null;
		
		IJavaSearchScope fScope		   = null;
		
		int			  fSearchFor	   = IJavaSearchConstants.FIELD;
		
		String		   fSearchText	  = "";								  //$NON-NLS-1$
																				  
		// 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 (JSPSearchSupport.DEBUG) {
						Logger.logException(e);
					}
				}
				// non-CoreExceptions will permanently stall the Worker thread
				catch (Exception e) {
					if (JSPSearchSupport.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 {
		
		IJavaElement	 fElement		 = null;
		
		boolean		  fIsCaseSensitive = false;
		
		int			  fLimitTo		 = IJavaSearchConstants.ALL_OCCURRENCES;
		
		int			  fMatchMode	   = SearchPattern.R_PATTERN_MATCH;
		
		SearchRequestor  fRequestor	   = null;
		
		IJavaSearchScope fScope		   = null;
		
		int			  fSearchFor	   = IJavaSearchConstants.FIELD;
		
		String		   fSearchText	  = "";								  //$NON-NLS-1$
																				  
		// 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();
					}
				}
			}
		}
	}
	
	// for debugging
	static final boolean			DEBUG;
	
	private static JSPSearchSupport singleton = null;
	
	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$
	}
	
	/**
	 * Clients should access the methods of this class via the single instance
	 * via getInstance()
	 * 
	 * @return
	 */
	public synchronized static JSPSearchSupport getInstance() {
		
		if (JSPSearchSupport.singleton == null) {
			JSPSearchSupport.singleton = new JSPSearchSupport();
		}
		return JSPSearchSupport.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;
	}
	
	// pa_TODO may be slow (esp for indexing entire workspace)
	private final CRC32			fChecksumCalculator = new CRC32();
	
	private IPath				  fJspPluginLocation  = null;
	
	/** main cancel montior for all search support */
	private final IProgressMonitor fMonitor			= new NullProgressMonitor();
	
	// end SearchRunnable
	
	private JSPSearchParticipant   fParticipant		= null;
	
	private JSPSearchSupport() {
		// force use of single instance
	}
	
	/**
	 * 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 (JSPSearchSupport.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 (JSPSearchSupport.DEBUG) {
					e.printStackTrace();
				}
			}
		}
		
		if (JSPSearchSupport.DEBUG) {
			System.out.println("scheduled" + delegate + "for indexing"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		
		return delegate;
	}
	
	// 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);
	}
	
	/**
	 * @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() && JSPSearchSupport.isJsp(jspFile)) {
			
			delegate = new JavaSearchDocumentDelegate(new JSPSearchDocument(jspFile.getFullPath().toString(), getSearchParticipant()));
		}
		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;
	}
	
	// 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 final IProgressMonitor getProgressMonitor() {
		
		return this.fMonitor;
	}
	
	/**
	 * 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;
	}
	
	JSPSearchParticipant getSearchParticipant() {
		
		if (this.fParticipant == null) {
			this.fParticipant = new JSPSearchParticipant();
		}
		return this.fParticipant;
	}
	
	/**
	 * JSP Indexing and Search jobs check this
	 * 
	 * @return
	 */
	public synchronized final boolean isCanceled() {
		
		return fMonitor.isCanceled();
	}
	
	/**
	 * 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();
	}
	
	/**
	 * 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
	 * 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();
		}
	}
	
	/**
	 * 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);
	}
}