/*******************************************************************************
 * Copyright (c) 2007, 2015 Ecliptical Software Inc. 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:
 *     Ecliptical Software Inc. - initial API and implementation
 *     IBM Canada - review initial contribution and commit
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.search;

import java.util.Iterator;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.ILaunchGroup;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.ui.search.ElementQuerySpecification;
import org.eclipse.jdt.ui.search.IMatchPresentation;
import org.eclipse.jdt.ui.search.IQueryParticipant;
import org.eclipse.jdt.ui.search.ISearchRequestor;
import org.eclipse.jdt.ui.search.PatternQuerySpecification;
import org.eclipse.jdt.ui.search.QuerySpecification;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.search.ui.text.Match;
import org.eclipse.ui.PartInitException;

/**
 * This class provides a search participant to find class references in the
 * {@linkplain IJavaLaunchConfigurationConstants#ATTR_MAIN_TYPE_NAME} attribute
 * of Java launch configurations
 *
 * @since 3.4.0
 */
public class LaunchConfigurationQueryParticipant implements IQueryParticipant {

	/**
	 * Singleton instance of the UI participant for the configuration
	 * search matches
	 */
	private UIParticipant uiParticipant;

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.ui.search.IQueryParticipant#estimateTicks(org.eclipse.jdt.ui.search.QuerySpecification)
	 */
	@Override
	public int estimateTicks(QuerySpecification query) {
		if (isValid(query)) {
			return 50;
		}
		return 0;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.ui.search.IQueryParticipant#getUIParticipant()
	 */
	@Override
	public synchronized IMatchPresentation getUIParticipant() {
		if (uiParticipant == null) {
			uiParticipant = new UIParticipant();
		}
		return uiParticipant;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.ui.search.IQueryParticipant#search(org.eclipse.jdt.ui.search.ISearchRequestor, org.eclipse.jdt.ui.search.QuerySpecification, org.eclipse.core.runtime.IProgressMonitor)
	 */
	@Override
	public void search(ISearchRequestor requestor, QuerySpecification query, IProgressMonitor monitor) throws CoreException {
		if (!isValid(query)) {
			return;
		}
		if(monitor == null) {
			monitor = new NullProgressMonitor();
		}
		monitor.beginTask("", 11); //$NON-NLS-1$
		try {
			Pattern pattern = null;
			if (query instanceof ElementQuerySpecification) {
				ElementQuerySpecification elementQuery = (ElementQuerySpecification) query;
				IJavaElement element = elementQuery.getElement();
				if(element instanceof IMember) {
					IMember member = (IMember) element;
					IType type = null;
					if(member.getElementType() == IJavaElement.TYPE) {
						type = (IType) member;
					}
					else if(member.getElementType() == IJavaElement.METHOD) {
						if(((IMethod)member).isMainMethod()) {
							type = member.getDeclaringType();
						}
					}
					if(type != null) {
						pattern = Pattern.compile(quotePattern(type.getFullyQualifiedName('$')));
					}
					else {
						return;
					}
				}
				else {
					return;
				}
			}
			if (query instanceof PatternQuerySpecification) {
				PatternQuerySpecification patternQuery = (PatternQuerySpecification) query;
				int flags = patternQuery.isCaseSensitive() ? 0
						: Pattern.CASE_INSENSITIVE;
				String quotedPattern = quotePattern(patternQuery.getPattern());
				pattern = Pattern.compile(quotedPattern, flags);
			}
			if(monitor.isCanceled()) {
				return;
			}
			monitor.worked(1);
			searchLaunchConfigurations(query.getScope(), requestor, pattern, new SubProgressMonitor(monitor, 7));
		} finally {
			monitor.done();
		}
	}

	/**
	 * Creates an adjusted pattern from the specified quote pattern
	 * @param pattern the search pattern to manipulate
	 * @return the original pattern adjusted to escape special chars in Java,and change Eclipse
	 * search chars to Java RegEx chars
	 */
	private String quotePattern(String pattern) {
		StringTokenizer t = new StringTokenizer(pattern, ".?*$()", true); //$NON-NLS-1$
		StringBuilder buf = new StringBuilder();
		String token = null;
		while (t.hasMoreTokens()) {
			token = t.nextToken();
			switch (token.charAt(0)) {
				case '.': {
					buf.append('\\');
					break;
				}
				case '?':
				case '*': {
					buf.append('.');
					break;
				}
				case '$': {
					buf.append('\\');
					break;
				}
				case '(': {
					buf.append('\\');
					break;
				}
				case ')': {
					buf.append('\\');
					break;
				}
			}
			buf.append(token);
		}
		return buf.toString();
	}

	/**
	 * Determines if the current query should be considered or not
	 * @param query the current query
	 * @return true if the query should be considered, false otherwise
	 */
	private boolean isValid(QuerySpecification query) {
		switch(query.getLimitTo()) {
			case IJavaSearchConstants.REFERENCES:
			case IJavaSearchConstants.ALL_OCCURRENCES: {
				break;
			}
			default: {
				return false;
			}
		}
		if (query instanceof ElementQuerySpecification) {
			IJavaElement element = ((ElementQuerySpecification) query).getElement();
			return element.getElementType() == IJavaElement.TYPE || element.getElementType() == IJavaElement.METHOD;
		}
		if (query instanceof PatternQuerySpecification) {
			PatternQuerySpecification patternQuery = (PatternQuerySpecification) query;
			switch (patternQuery.getSearchFor()) {
				case IJavaSearchConstants.UNKNOWN:
				case IJavaSearchConstants.TYPE:
				case IJavaSearchConstants.CLASS:
				case IJavaSearchConstants.CLASS_AND_INTERFACE:
				case IJavaSearchConstants.CLASS_AND_ENUM: {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Returns the success of the the pattern matching
	 * @param scope the search scope
	 * @param config the backing {@link ILaunchConfiguration}
	 * @param pattern the search pattern
	 * @return true if there were matching elements for the pattern, false otherwise
	 * @throws CoreException if an exception occurs
	 */
	private boolean matches(IJavaSearchScope scope, ILaunchConfiguration config, Pattern pattern) throws CoreException {
		if(!config.exists() || !config.getType().isPublic() || !DebugUIPlugin.doLaunchConfigurationFiltering(config)) {
			return false;
		}
		String mainTypeName = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, (String) null);
		if (mainTypeName == null) {
			return false;
		}
		try {
			mainTypeName = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(mainTypeName);
		}
		catch(CoreException ce) {
			return false;
		}
		if (! pattern.matcher(mainTypeName).matches()) {
			return false;
		}
		IResource[] resources = config.getMappedResources();
		if (resources != null) {
			for (int i = 0; i < resources.length; i++) {
				if (scope.encloses(resources[i].getFullPath().toString())) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Searches for configurations matching the specified pattern
	 * @param scope the search scope
	 * @param requestor the requester
	 * @param pattern the search pattern
	 * @param monitor for progress monitoring
	 * @throws CoreException if an exception occurs
	 */
	private void searchLaunchConfigurations(IJavaSearchScope scope, ISearchRequestor requestor, Pattern pattern, IProgressMonitor monitor) throws CoreException {
		ILaunchConfiguration[] configs = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurations();
		monitor.beginTask("Searching for launch configurations", configs.length); //$NON-NLS-1$
		try {
			for (int i = 0; i < configs.length; ++i) {
				if (monitor.isCanceled()) {
					return;
				}
				monitor.worked(1);
				if (matches(scope, configs[i], pattern)) {
					requestor.reportMatch(new Match(configs[i], 0, 0));
				}
			}
		} finally {
			monitor.done();
		}
	}

	/**
	 * The UI participant for showing configuration matches in the search view
	 *
	 * @since 3.4.0
	 */
	private static class UIParticipant implements IMatchPresentation {

		/* (non-Javadoc)
		 * @see org.eclipse.jdt.ui.search.IMatchPresentation#createLabelProvider()
		 */
		@Override
		public ILabelProvider createLabelProvider() {
			return DebugUITools.newDebugModelPresentation();
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jdt.ui.search.IMatchPresentation#showMatch(org.eclipse.search.ui.text.Match, int, int, boolean)
		 */
		@Override
		public void showMatch(Match match, int currentOffset, int currentLength, boolean activate) throws PartInitException {
			Object o = match.getElement();
			if (o instanceof ILaunchConfiguration) {
				if (activate) {
					try {
						ILaunchConfiguration config = (ILaunchConfiguration) o;
						Set<Set<String>> modes =  config.getType().getSupportedModeCombinations();
						ILaunchGroup group = null;
						Set<String> mode = null;
						for (Iterator<Set<String>> iter = modes.iterator(); iter.hasNext();) {
							mode = iter.next();
							if(mode.size() == 1) {
								group = DebugUITools.getLaunchGroup(config, mode.iterator().next());
								if (group != null) {
									break;
								}
							}
						}
						if (group == null || !config.exists()) {
							return;
						}
						DebugUITools.openLaunchConfigurationDialog(JDIDebugUIPlugin.getActiveWorkbenchShell(), config, group.getIdentifier(), Status.OK_STATUS);
					}
					catch(CoreException ce) {
						JDIDebugUIPlugin.log(ce);
					}
				}
			}
		}
	}
}
