/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.debug.internal.ui.launchConfigurations;


import java.io.IOException;
import java.io.StringReader;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.xerces.dom.DocumentImpl;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchListener;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.WorkbenchException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * The perspective manager manages the 'perspective' settings
 * defined by launch configurations. Specifically it: <ul>
 * <li>changes perspectives as launches are registered</li>
 * <li>change perspective when a thread suspends</li>
 * </ul>
 * 
 * @see IDebugUIContants.ATTR_RUN_PERSPECTIVE
 * @see IDebugUIContants.ATTR_DEBUG_PERSPECTIVE
 */
public class PerspectiveManager implements ILaunchListener, IDebugEventSetListener {
		
	/**
	 * Table of config types to tables of user specified perspective settings (mode ids
	 * to perspective ids).
	 */	
	private Map fPreferenceMap;
	
	// XML tags
	private static final String ELEMENT_PERSPECTIVES = "launchPerspectives"; //$NON-NLS-1$
	private static final String ELEMENT_PERSPECTIVE = "launchPerspective"; //$NON-NLS-1$
	private static final String ATTR_TYPE_ID = "configurationType"; //$NON-NLS-1$
	private static final String ATTR_MODE_ID = "mode"; //$NON-NLS-1$
	private static final String ATTR_PERSPECTIVE_ID = "perspective";  //$NON-NLS-1$
		
	/**
	 * Called by the debug ui plug-in on startup.
	 * The perspective manager starts listening for
	 * launches to be registered.
	 */
	public void startup() {
		DebugPlugin plugin = DebugPlugin.getDefault();
		plugin.getLaunchManager().addLaunchListener(this);
		plugin.addDebugEventListener(this);
	}

	/**
	 * Called by the debug ui plug-in on shutdown.
	 * The perspective manager de-registers as a 
	 * launch listener.
	 */
	public void shutdown() {
		DebugPlugin plugin = DebugPlugin.getDefault();
		plugin.getLaunchManager().removeLaunchListener(this);
		plugin.removeDebugEventListener(this);
	}

	/**
	 * Do nothing.
	 * 
	 * @see ILaunchListener#launchRemoved(ILaunch)
	 */
	public void launchRemoved(ILaunch launch) {
	}
	
	/**
	 * Do nothing.
	 * 
	 * @see ILaunchListener#launchChanged(ILaunch)
	 */
	public void launchChanged(ILaunch launch) {
	}	

	/** 
	 * Switch to the perspective specified by the
	 * launch configuration.
	 * 
	 * @see ILaunchListener#launchAdded(ILaunch)
	 */
	public void launchAdded(ILaunch launch) {
		String perspectiveId = null;
		// check event filters
		try {
			perspectiveId = getPerspectiveId(launch);
		} catch (CoreException e) {
			String name = DebugUIPlugin.getModelPresentation().getText(launch);
			switchFailed(e, name);
		}
		
		// don't switch if a private config
		ILaunchConfiguration configuration = launch.getLaunchConfiguration();
		if (configuration != null) {
			if (!LaunchConfigurationManager.isVisible(configuration)) {
				perspectiveId = null;
			}
		}
		
		// switch
		if (perspectiveId != null) {
			switchToPerspective(perspectiveId);
		}
	}


	/**
	 * Switches to the specified perspective
	 * 
	 * @param id perspective identifier
	 */
	protected void switchToPerspective(final String id) {
		async(new Runnable() {
			public void run() {
				IWorkbenchWindow window = DebugUIPlugin.getActiveWorkbenchWindow();
				if (window != null) {
					try {
						window.getWorkbench().showPerspective(id, window);
					} catch (WorkbenchException e) {
						DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(),
						LaunchConfigurationsMessages.getString("PerspectiveManager.Error_1"),  //$NON-NLS-1$
						MessageFormat.format(LaunchConfigurationsMessages.getString("PerspectiveManager.Unable_to_switch_to_perspective__{0}_2"), new String[]{id}), //$NON-NLS-1$
						e);
					}
				}
			}
		});	
	}
	
	/**
	 * Utility method to submit an asnychronous runnable to the UI
	 */
	protected void async(Runnable r) {
		Display d = DebugUIPlugin.getStandardDisplay();
		if (d != null && !d.isDisposed()) {
			d.asyncExec(r);
		}
	}
	
	/**
	 * Utility method to submit a synchronous runnable to the UI
	 */
	protected void sync(Runnable r) {
		Display d = DebugUIPlugin.getStandardDisplay();
		if (d != null && !d.isDisposed()) {
			d.syncExec(r);
		}
	}	

	/**
	 * Reports failure to switch perspectives to the user
	 * 
	 * @param status exception status describing failure
	 * @param launchName the name of the launch that the
	 *  failure is associated with
	 */
	protected void switchFailed(final Throwable t, final String launchName) {
		sync(new Runnable() {
			public void run() {
				DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(), LaunchConfigurationsMessages.getString("PerspectiveManager.Error_1"),  //$NON-NLS-1$
				 MessageFormat.format(LaunchConfigurationsMessages.getString("PerspectiveManager.Unable_to_switch_perpsectives_as_specified_by_launch__{0}_4"), new String[] {launchName}), //$NON-NLS-1$
				 t);
			}});
	}
	
	/**
	 * On a SUSPEND event, show the debug view. If no debug view is open,
	 * switch to the perspective specified by the launcher.
	 *
	 * @see IDebugEventSetListener#handleDebugEvents(DebugEvent[])
	 */
	public void handleDebugEvents(DebugEvent[] events) {
		// open the debugger if this is a suspend event and the debug view is not yet open
		// and the preferences are set to switch
		for (int i = 0; i < events.length; i++) {
			DebugEvent event = events[i];
			if (event.getKind() == DebugEvent.SUSPEND && (event.getDetail() == DebugEvent.BREAKPOINT || event.getDetail() == DebugEvent.STEP_END)) {
				// apply event filters
				ILaunch launch = null;
				Object source = event.getSource();
				if (source instanceof IDebugElement) {
					launch = ((IDebugElement)source).getLaunch();
				} else if (source instanceof IProcess) {
					launch = ((IProcess)source).getLaunch();
				}
				String perspectiveId = null;
				try {
					perspectiveId = getPerspectiveId(launch);
				} catch (CoreException e) {
					DebugUIPlugin.log(e);
				}
				// if no perspective specified, always switch to debug
				// perspective 

				// this has to be done in an asynch, such that the workbench
				// window can be accessed
				final String id = perspectiveId;
				Runnable r = new Runnable() {
					public void run() {
						String targetId = id;
						IWorkbenchWindow window = DebugUIPlugin.getActiveWorkbenchWindow();
						if (window == null) {
							return;
						}
						if (targetId == null) {
							IWorkbenchPage page = window.getActivePage();
							if (page != null) {
								IViewPart part = page.findView(IDebugUIConstants.ID_DEBUG_VIEW);
								if (part == null) {
									targetId = IDebugUIConstants.ID_DEBUG_PERSPECTIVE;
								}
							}
						}
						if (targetId != null) {
							// re-open the window if minimized 
							Shell shell= window.getShell();
							if (shell != null) {
								if (shell.getMinimized()) {
									shell.setMinimized(false);
								}
								if (DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_ACTIVATE_WORKBENCH)) {
									shell.forceActive();
								}
							}				
							switchToPerspective(targetId);
						}
					}
				};
				async(r);
			}
		}
	}	
	
	/** 
	 * Returns the perspective associated with the
	 * given launch, or <code>null</code> if none.
	 * 
	 * @param launch a launch
	 * @return the perspective associated with the launch,
	 * 	or <code>null</code>
	 * @exception CoreException if unable to retrieve a required
	 *  launch configuration attribute
	 */
	protected String getPerspectiveId(ILaunch launch) throws CoreException {
		if (launch == null) {
			return null;
		}
		ILaunchConfiguration config = launch.getLaunchConfiguration();
		if (config == null) {
			return null;
		}
		String perspectiveId = null;
		perspectiveId = DebugUITools.getLaunchPerspective(config.getType(), launch.getLaunchMode());
		if (perspectiveId != null && perspectiveId.equals(IDebugUIConstants.PERSPECTIVE_NONE)) {
			perspectiveId = null;
		}
		return perspectiveId;
	}
	
	/**
	 * Returns the perspective to switch to when a configuration of the given type
	 * is launched in the given mode, or <code>null</code> if no switch should take
	 * place.
	 * 
	 * @param type launch configuration type
	 * @param mode launch mode identifier
	 * @return perspective identifier or <code>null</code>
	 * @since 3.0
	 */
	public String getLaunchPerspective(ILaunchConfigurationType type, String mode) {
		String id = getUserSpecifiedLaunchPerspective(type, mode);
		if (id == null) {
			// get the default
			id = getDefaultLaunchPerspective(type, mode);
		} else if (id.equals(IDebugUIConstants.PERSPECTIVE_NONE)) {
			// translate NONE to null
			id = null;
		}
		return id;
	}
	
	/**
	 * Sets the perspective to switch to when a configuration of the given type
	 * is launched in the given mode. <code>PERSPECTIVE_NONE</code> indicates no
	 * perspective switch should take place. <code>PERSPECTIVE_DEFAULT</code> indicates
	 * a default perspective switch should take place, as defined by the associated
	 * launch tab group extension. Saves plug-in preferences.
	 * 
	 * @param type launch configuration type
	 * @param mode launch mode identifier
	 * @param perspective identifier, <code>PERSPECTIVE_NONE</code>, or
	 *   <code>PERSPECTIVE_DEFAULT</code>
	 * @since 3.0
	 */
	public void setLaunchPerspective(ILaunchConfigurationType type, String mode, String perspective) {
		internalSetLaunchPerspective(type.getIdentifier(), mode, perspective);
		// update preference
		String xml;
		try {
			xml = generatePerspectiveXML();
			DebugUIPlugin.getDefault().getPreferenceStore().putValue(IInternalDebugUIConstants.PREF_LAUNCH_PERSPECTIVES, xml);
			DebugUIPlugin.getDefault().savePluginPreferences();				
		} catch (IOException e) {
			DebugUIPlugin.log(DebugUIPlugin.newErrorStatus(LaunchConfigurationsMessages.getString("PerspectiveManager.9"), e)); //$NON-NLS-1$
		}
	}
	
	/**
	 * Sets the perspective to switch to when a configuration of the given type
	 * is launched in the given mode. <code>PERSPECTIVE_NONE</code> indicates no
	 * perspective switch should take place. <code>PERSPECTIVE_DEFAULT</code> indicates
	 * a default perspective switch should take place, as defined by the associated
	 * launch tab group extension.
	 * 
	 * @param type launch configuration type identifier
	 * @param mode launch mode identifier
	 * @param perspective identifier, <code>PERSPECTIVE_NONE</code>, or
	 *   <code>PERSPECTIVE_DEFAULT</code>
	 * @since 3.0
	 */
	private void internalSetLaunchPerspective(String type, String mode, String perspective) {
		Map modeMap = (Map)fPreferenceMap.get(type);
		if (modeMap == null) {
			modeMap = new HashMap();
			fPreferenceMap.put(type, modeMap);
		}
		if (perspective.equals(IDebugUIConstants.PERSPECTIVE_DEFAULT)) {
			// remove user preference setting
			modeMap.remove(mode);
		} else {
			// override default setting
			modeMap.put(mode, perspective);
		}
	}
	
	/**
	 * Generates XML for the user specified perspective settings.
	 *  
	 * @return XML
	 * @exception CoreException if unable to generate the XML
	 */
	private String generatePerspectiveXML() throws IOException {
		
		Document doc = new DocumentImpl();
		Element configRootElement = doc.createElement(ELEMENT_PERSPECTIVES);
		doc.appendChild(configRootElement);
		
		Iterator configTypes = fPreferenceMap.keySet().iterator();
		while (configTypes.hasNext()) {
			String type = (String)configTypes.next();
			Map modeMap = (Map)fPreferenceMap.get(type);
			if (modeMap != null && !modeMap.isEmpty()) {
				Iterator modes = modeMap.keySet().iterator();
				while (modes.hasNext()) {
					String mode = (String)modes.next();
					String perspective = (String)modeMap.get(mode);
					Element element = doc.createElement(ELEMENT_PERSPECTIVE);
					element.setAttribute(ATTR_TYPE_ID, type);
					element.setAttribute(ATTR_MODE_ID, mode);
					element.setAttribute(ATTR_PERSPECTIVE_ID, perspective);
					configRootElement.appendChild(element);
				}
			}			
		}

		return DebugUIPlugin.serializeDocument(doc);		
	}

	/**
	 * Returns the default perspective to switch to when a configuration of the given
	 * type is lanuched in the given mode, or <code>null</code> if none.
	 * 
	 * @param type launch configuration type
	 * @param mode launch mode
	 * @return perspective identifier, or <code>null</code>
	 */
	protected String getDefaultLaunchPerspective(ILaunchConfigurationType type, String mode) {
		LaunchConfigurationTabGroupExtension extension = LaunchConfigurationPresentationManager.getDefault().getExtension(type.getIdentifier(), mode);
		if (extension != null) {
			String id = extension.getPerspective(mode);
			if (id == null) {
				// revert to hard coded default (for backwards compatibility)
				// since nothing is specified in XML
				if (mode.equals(ILaunchManager.DEBUG_MODE)) {
					return IDebugUIConstants.ID_DEBUG_PERSPECTIVE;
				}	
			} else {
				return id;
			}
		}
		return null;
	}
	
	/**
	 * Returns the user specified perspective to switch to when a configuration of the
	 * given type is lanuched in the given mode, or <code>null</code> if unspecified.
	 * Returns <code>PERSPECTIVE_NONE</code> to indicate no switch
	 * 
	 * @param type launch configuration type
	 * @param mode launch mode
	 * @return perspective identifier, <code>PERSPECTIVE_NONE</code>, or <code>null</code>
	 */
	protected String getUserSpecifiedLaunchPerspective(ILaunchConfigurationType type, String mode) {
		String id = null;
		if (fPreferenceMap == null) {
			initPerspectives();
		}
		Map modeMap = (Map)fPreferenceMap.get(type.getIdentifier());
		if (modeMap != null) {
			id = (String)modeMap.get(mode);
		}
		return id;
	}

	/**
	 * Initialize the preference map with settings from user preference
	 */
	private void initPerspectives() {
		fPreferenceMap = new HashMap();
		String xml = DebugUIPlugin.getDefault().getPreferenceStore().getString(IInternalDebugUIConstants.PREF_LAUNCH_PERSPECTIVES);
		if (xml != null && xml.length() > 0) {
			try {
				Element root = null;
				DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
				StringReader reader = new StringReader(xml);
				InputSource source = new InputSource(reader);
				root = parser.parse(source).getDocumentElement();
				
				NodeList list = root.getChildNodes();
				int length = list.getLength();
				for (int i = 0; i < length; ++i) {
					Node node = list.item(i);
					short nt = node.getNodeType();
					if (nt == Node.ELEMENT_NODE) {
						Element element = (Element) node;
						String nodeName = element.getNodeName();
						if (nodeName.equalsIgnoreCase(ELEMENT_PERSPECTIVE)) {
							String type = element.getAttribute(ATTR_TYPE_ID);
							String mode = element.getAttribute(ATTR_MODE_ID);
							String perpsective = element.getAttribute(ATTR_PERSPECTIVE_ID);
							internalSetLaunchPerspective(type, mode, perpsective);
						}
					}
				}				
			} catch (ParserConfigurationException e) {
				DebugUIPlugin.log(e);			
			} catch (SAXException e) {
				DebugUIPlugin.log(e);
			} catch (IOException e) {
				DebugUIPlugin.log(e);
			}
		}
		
	}
	
}
