/*******************************************************************************
 * Copyright (c) 2007, 2015 Ecliptical Software Inc. and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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 (IResource resource : resources) {
				if (scope.encloses(resource.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 (ILaunchConfiguration config : configs) {
				if (monitor.isCanceled()) {
					return;
				}
				monitor.worked(1);
				if (matches(scope, config, pattern)) {
					requestor.reportMatch(new Match(config, 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);
					}
				}
			}
		}
	}
}
