/*******************************************************************************
 * Copyright (c) 2000, 2005 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.jdt.debug.ui;


import java.text.MessageFormat;
import java.util.HashMap;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.IPersistableSourceLocator;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.debug.core.IJavaReferenceType;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.internal.debug.ui.DebugUIMessages;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.debug.ui.launcher.LauncherMessages;
import org.eclipse.jdt.internal.debug.ui.launcher.SourceElementLabelProvider;
import org.eclipse.jdt.internal.debug.ui.launcher.SourceElementQualifierProvider;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.sourcelookup.IJavaSourceLocation;
import org.eclipse.jdt.launching.sourcelookup.JavaSourceLocator;
import org.eclipse.jface.window.Window;
import org.eclipse.ui.dialogs.TwoPaneElementSelector;

/**
 * A source locator that prompts the user to find source when source cannot
 * be found on the current source lookup path.
 * <p>
 * This class is intended to be instantiated. This class is not
 * intended to be subclassed.
 * </p>
 * @since 2.0
 * @deprecated In 3.0, the debug platform provides source lookup facilities that
 *  should be used in place of the Java source lookup support provided in 2.0.
 *  The new facilities provide a source lookup director that coordinates source
 *  lookup among a set of participants, searching a set of source containers.
 *  See the following packages: <code>org.eclipse.debug.core.sourcelookup</code>
 *  and <code>org.eclipse.debug.core.sourcelookup.containers</code>. This class
 *  has been replaced by a Java source lookup director and Java source lookup
 *  participant. To migrate to the new source lookup support clients should
 *  add two new attributes to their launch configuration type extensions:<ul>
 *  <li>sourceLocatorId="org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector"</li>
 *  <li>sourcePathComputerId="org.eclipse.jdt.launching.sourceLookup.javaSourcePathComputer"</li>
 *  </ul>
 *  The source locator id attribute specifies to use the Java source lookup director
 *  for launch configurations of the associated type, and the source path computer id
 *  attribute specifies the class to use when computing a default source lookup
 *  path for a launch configuration. The path computer referenced/provided (by the
 *  above id), computes a default source lookup path based on the support provided in
 *  the 2.0 release - i.e. a configuration's <code>ATTR_SOURCE_PATH_PROVIDER</code>
 *  attribute (if present), or a default source lookup path based on a configuration's
 *  runtime classpath. This class has been replaced by the Java source lookup
 *  director which is an internal class, but can be used via the
 *  <code>sourceLocatorId</code> attribute on a launch configuration type extension.
 */

public class JavaUISourceLocator implements IPersistableSourceLocator {

	/**
	 * Identifier for the 'Prompting Java Source Locator' extension
	 * (value <code>"org.eclipse.jdt.debug.ui.javaSourceLocator"</code>).
	 */
	public static final String ID_PROMPTING_JAVA_SOURCE_LOCATOR = IJavaDebugUIConstants.PLUGIN_ID + ".javaSourceLocator"; //$NON-NLS-1$

	/**
	 * Launch configuration attribute indicating that this source locator should
	 * locate all source elements that correspond to a stack frame, rather than
	 * the first match. Default value is <code>false</code>.
	 * 
	 * @since 2.1
	 */
	public static final String ATTR_FIND_ALL_SOURCE_ELEMENTS = IJavaDebugUIConstants.PLUGIN_ID + ".ATTR_FIND_ALL_SOURCE_ELEMENTS"; //$NON-NLS-1$

	/**
	 * The project being debugged.
	 */
	private IJavaProject fJavaProject;

	/**
	 * Underlying source locator.
	 */
	private JavaSourceLocator fSourceLocator;

	/**
	 * Whether the user should be prompted for source.
	 * Initially true, until the user checks the 'do not
	 * ask again' box.
	 */
	private boolean fAllowedToAsk;

	/**
	 * Whether to find all source elements for a stack frame (in case of
	 * dupliucates), or just the first match.
	 */
	private boolean fIsFindAllSourceElements = false;
	
	/**
	 * A cache of types to associated source elements (when duplicates arise and
	 * the users chooses a source element, it is remembered).
	 */
	private HashMap fTypesToSource = null;

	/**
	 * Constructs an empty source locator.
	 */
	public JavaUISourceLocator() {
		fSourceLocator = new JavaSourceLocator();
		fAllowedToAsk = true;
	}

	/**
	 * Constructs a new source locator that looks in the
	 * specified project for source, and required projects, if
	 * <code>includeRequired</code> is <code>true</code>.
	 * 
	 * @param projects the projects in which to look for source
	 * @param includeRequired whether to look in required projects
	 * 	as well
	 */
	public JavaUISourceLocator(
		IJavaProject[] projects,
		boolean includeRequired)
		throws JavaModelException {
		fSourceLocator = new JavaSourceLocator(projects, includeRequired);
		fAllowedToAsk = true;
	}

	/**
	 * Constructs a source locator that searches for source
	 * in the given Java project, and all of its required projects,
	 * as specified by its build path or default source lookup
	 * settings.
	 * 
	 * @param project Java project
	 * @exception CoreException if unable to read the project's
	 * 	 build path
	 */
	public JavaUISourceLocator(IJavaProject project) throws CoreException {
		fJavaProject = project;
		IJavaSourceLocation[] sls =
			JavaSourceLocator.getDefaultSourceLocations(project);
		fSourceLocator = new JavaSourceLocator(project);
		if (sls != null) {
			fSourceLocator.setSourceLocations(sls);
		}
		fAllowedToAsk = true;
	}

	/**
	 * @see org.eclipse.debug.core.model.ISourceLocator#getSourceElement(IStackFrame)
	 */
	public Object getSourceElement(IStackFrame stackFrame) {
		Object res = findSourceElement(stackFrame);
		if (res == null && fAllowedToAsk) {
			IJavaStackFrame frame =
				(IJavaStackFrame) stackFrame.getAdapter(IJavaStackFrame.class);
			if (frame != null) {
				try {
					if (!frame.isObsolete()) {
						showDebugSourcePage(frame);
						res = fSourceLocator.getSourceElement(stackFrame);
					}
				} catch (DebugException e) {
				}
			}
		}
		return res;
	}

	private Object findSourceElement(IStackFrame stackFrame) {
		if (isFindAllSourceElements()) {
			Object[] sourceElements = fSourceLocator.getSourceElements(stackFrame);
			if (sourceElements == null || sourceElements.length == 0) {
				return null;
			} 
			if (sourceElements.length == 1) {
				return sourceElements[0];
			}
			try {
				IJavaStackFrame frame = (IJavaStackFrame)stackFrame;
				IJavaReferenceType type = frame.getReferenceType();
				Object cachedSource = getSourceElement(type);
				if (cachedSource != null) {
					return cachedSource;
				}
				// prompt
				TwoPaneElementSelector dialog = new TwoPaneElementSelector(JDIDebugUIPlugin.getActiveWorkbenchShell(), new SourceElementLabelProvider(),new SourceElementQualifierProvider());
				dialog.setTitle(DebugUIMessages.JavaUISourceLocator_Select_Source_1); 
				dialog.setMessage(MessageFormat.format(DebugUIMessages.JavaUISourceLocator__Select_the_source_that_corresponds_to__0__2, new String[]{type.getName()})); 
				dialog.setElements(sourceElements);
				dialog.setMultipleSelection(false);
				dialog.setUpperListLabel(DebugUIMessages.JavaUISourceLocator__Matching_files__3); 
				dialog.setLowerListLabel(DebugUIMessages.JavaUISourceLocator__Location__4); 
				dialog.open();
				Object[] result = dialog.getResult();
				if (result == null) {
					return null;
				}
				Object sourceElement = result[0];
				cacheSourceElement(sourceElement, type);
				return sourceElement;
			} catch (CoreException e) {
				JDIDebugUIPlugin.log(e);
				return sourceElements[0];
			}
		}
		return fSourceLocator.getSourceElement(stackFrame);
	}
	
	private Object getSourceElement(IJavaReferenceType type) {
		if (fTypesToSource == null) {
			return null; 
		}
		return fTypesToSource.get(type);
	}
	
	private void cacheSourceElement(Object sourceElement, IJavaReferenceType type) {
		if (fTypesToSource == null) {
			fTypesToSource = new HashMap();
		}
		fTypesToSource.put(type, sourceElement);
	}

	/**
	 * Prompts to locate the source of the given type. Prompts in the UI
	 * thread, since a source lookup could be the result of a conditional
	 * breakpoint looking up source for an evaluation, from the event
	 * dispatch thread.
	 * 
	 * @param typeName the name of the type for which source
	 *  could not be located
	 */
	private void showDebugSourcePage(final IJavaStackFrame frame) {
		Runnable prompter = new Runnable() {
			public void run() {
				try {
					String message = MessageFormat.format(LauncherMessages.JavaUISourceLocator_selectprojects_message, new String[] {frame.getDeclaringTypeName()});

					ILaunchConfiguration configuration =
						frame.getLaunch().getLaunchConfiguration();
					JavaSourceLookupDialog dialog =
						new JavaSourceLookupDialog(
							JDIDebugUIPlugin.getActiveWorkbenchShell(),
							message,
							configuration);
					int result = dialog.open();
					if (result == Window.OK) {
						fAllowedToAsk = !dialog.isNotAskAgain();
						JavaUISourceLocator.this.initializeDefaults(
							configuration);
					}
				} catch (CoreException e) {
					// only report an error if the thread has not resumed
					if (e.getStatus().getCode()
						!= IJavaThread.ERR_THREAD_NOT_SUSPENDED) {
						JDIDebugUIPlugin.log(e);
					}
				}
			}
		};
		JDIDebugUIPlugin.getStandardDisplay().syncExec(prompter);
	}

	/**
	 * @see IPersistableSourceLocator#getMemento()
	 */
	public String getMemento() throws CoreException {
		String memento = fSourceLocator.getMemento();
		String handle = fJavaProject.getHandleIdentifier();
		String findAll = Boolean.valueOf(isFindAllSourceElements()).toString();

		StringBuffer buffer = new StringBuffer();
		buffer.append("<project>"); //$NON-NLS-1$
		buffer.append(handle);
		buffer.append("</project>"); //$NON-NLS-1$
		buffer.append("<findAll>"); //$NON-NLS-1$
		buffer.append(findAll);
		buffer.append("</findAll>"); //$NON-NLS-1$
		buffer.append(memento);
		return buffer.toString();
	}

	/**
	 * @see IPersistableSourceLocator#initializeDefaults(ILaunchConfiguration)
	 */
	public void initializeDefaults(ILaunchConfiguration configuration)
		throws CoreException {
		fSourceLocator.initializeDefaults(configuration);
		fJavaProject = JavaRuntime.getJavaProject(configuration);
		fIsFindAllSourceElements =
			configuration.getAttribute(ATTR_FIND_ALL_SOURCE_ELEMENTS, false);
	}

	/**
	 * @see IPersistableSourceLocator#initializeFromMemento(String)
	 */
	public void initializeFromMemento(String memento) throws CoreException {
		if (memento.startsWith("<project>")) { //$NON-NLS-1$
			int index = memento.indexOf("</project>"); //$NON-NLS-1$
			if (index > 0) {
				String handle = memento.substring(9, index);
				int start = index + 19;
				index = memento.indexOf("</findAll>", start); //$NON-NLS-1$
				if (index > 0) {
					String findAll = memento.substring(start, index);
					Boolean all = Boolean.valueOf(findAll);
					String rest = memento.substring(index + 10);
					fJavaProject = (IJavaProject) JavaCore.create(handle);
					fIsFindAllSourceElements = all.booleanValue();
					fSourceLocator.initializeFromMemento(rest);
				}
			}
		} else {
			// OLD FORMAT
			int index = memento.indexOf('\n');
			String handle = memento.substring(0, index);
			String rest = memento.substring(index + 1);
			fJavaProject = (IJavaProject) JavaCore.create(handle);
			fIsFindAllSourceElements = false;
			fSourceLocator.initializeFromMemento(rest);
		}
	}

	/**
	 * @see JavaSourceLocator#getSourceLocations()
	 */
	public IJavaSourceLocation[] getSourceLocations() {
		return fSourceLocator.getSourceLocations();
	}

	/**
	 * @see JavaSourceLocator#setSourceLocations(IJavaSourceLocation[])
	 */
	public void setSourceLocations(IJavaSourceLocation[] locations) {
		fSourceLocator.setSourceLocations(locations);
	}

	/**
	 * Returns whether this source locator is configured to search for all
	 * source elements that correspond to a stack frame. When <code>false</code>
	 * is returned, searching stops on the first match. If there is more than
	 * one source element that corresponds to a stack frame, the user is
	 * prompted to choose a source element to open.
	 * 
	 * @return whether this source locator is configured to search for all
	 * source elements that correspond to a stack frame
	 * @since 2.1
	 */
	public boolean isFindAllSourceElements() {
		return fIsFindAllSourceElements;
	}

	/**
	 * Sets whether this source locator is configured to search for all source
	 * elements that correspond to a stack frame, or the first match.
	 * 
	 * @param findAll whether this source locator should search for all source
	 * elements that correspond to a stack frame
	 * @since 2.1
	 */
	public void setFindAllSourceElement(boolean findAll) {
		fIsFindAllSourceElements = findAll;
	}

}
