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

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

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
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.ILaunchesListener;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.ui.IValueDetailListener;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.debug.core.IEvaluationRunnable;
import org.eclipse.jdt.debug.core.IJavaArray;
import org.eclipse.jdt.debug.core.IJavaArrayType;
import org.eclipse.jdt.debug.core.IJavaClassType;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaPrimitiveValue;
import org.eclipse.jdt.debug.core.IJavaReferenceType;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.core.IJavaType;
import org.eclipse.jdt.debug.core.IJavaValue;
import org.eclipse.jdt.debug.eval.IAstEvaluationEngine;
import org.eclipse.jdt.debug.eval.ICompiledExpression;
import org.eclipse.jdt.debug.eval.IEvaluationListener;
import org.eclipse.jdt.debug.eval.IEvaluationResult;
import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;

import com.sun.jdi.InvocationException;

public class JavaDetailFormattersManager implements IPropertyChangeListener, IDebugEventSetListener, ILaunchesListener {
	/**
	 * The default detail formatters manager.
	 */
	static private JavaDetailFormattersManager fgDefault;
	
	/**
	 * Return the default detail formatters manager.
	 * 
	 * @return default detail formatters manager.
	 */
	static public JavaDetailFormattersManager getDefault() {
		if (fgDefault == null) {
			fgDefault= new JavaDetailFormattersManager();
		}
		return fgDefault;
	}
	
	/**
	 * Map of types to the associated formatter (code snippet).
	 * (<code>String</code> -> <code>String</code>)
	 */
	private HashMap fDetailFormattersMap;
	
	/**
	 * Cache of compiled expressions.
	 * Associate a pair type name/debug target to a compiled expression.
	 */
	private HashMap fCacheMap;
	
	/**
	 * JavaDetailFormattersManager constructor.
	 */
	private JavaDetailFormattersManager() {
		populateDetailFormattersMap();
		JDIDebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
		DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
		DebugPlugin.getDefault().addDebugEventListener(this);
		fCacheMap= new HashMap();
	}
	
	/**
	 * Populate the detail formatters map with data from preferences.
	 */
	private void populateDetailFormattersMap() {
		String[] detailFormattersList= JavaDebugOptionsManager.parseList(JDIDebugUIPlugin.getDefault().getPreferenceStore().getString(IJDIPreferencesConstants.PREF_DETAIL_FORMATTERS_LIST));
		fDetailFormattersMap= new HashMap(detailFormattersList.length / 3);
		for (int i= 0, length= detailFormattersList.length; i < length;) {
			String typeName= detailFormattersList[i++];
			String snippet= detailFormattersList[i++].replace('\u0000', ',');
			boolean enabled= ! JavaDetailFormattersPreferencePage.DETAIL_FORMATTER_IS_DISABLED.equals(detailFormattersList[i++]);
			fDetailFormattersMap.put(typeName, new DetailFormatter(typeName, snippet, enabled));
		}
	}
	
	/**
	 * Compute asynchronously the 'toString' of the given value. If a formatter is associated to
	 * the type of the given value, this formatter is used instead of the <code>toString()</code>
	 * method.
	 * The result is return through the listener.
	 * 
	 * @param objectValue the value to 'format' 
	 * @param thread the thread to use to performed the evaluation
	 * @param listener the listener
	 */	
	public void computeValueDetail(final IJavaValue objectValue, final IJavaThread thread, final IValueDetailListener listener) {
		Runnable postEventDispatch = new Runnable() {
			public void run() {
				Runnable postEventProcess = new Runnable() {
					public void run() {
						if (thread.isPerformingEvaluation() && thread.isSuspended()) {
							listener.detailComputed(objectValue, DebugUIMessages.getString("JavaDetailFormattersManager.9")); //$NON-NLS-1$
						} else {
							thread.queueRunnable(new Runnable() {
								public void run() {
									resolveFormatter(objectValue, thread, listener);
								}
							});
						}
					}
				};
				JDIDebugUIPlugin.getStandardDisplay().asyncExec(postEventProcess);
			}
		};
		DebugPlugin.getDefault().asyncExec(postEventDispatch);
	}
	
	private void resolveFormatter(final IJavaValue value, final IJavaThread thread, final IValueDetailListener listener) {
		ICompiledExpression compiledExpression= null;
		EvaluationListener evaluationListener= new EvaluationListener(value, thread, listener);
		if (value instanceof IJavaObject && !(value instanceof IJavaArray)) {
			IJavaObject objectValue= (IJavaObject) value;
			IJavaProject project= getJavaProject(thread);
			if (project != null) {
				// get the evaluation engine
				JDIDebugTarget debugTarget= (JDIDebugTarget) thread.getDebugTarget();
				IAstEvaluationEngine evaluationEngine= JDIDebugUIPlugin.getDefault().getEvaluationEngine(project, debugTarget);
				// get the compiled expression to use
				try {
					compiledExpression= getCompiledExpression(objectValue, debugTarget, evaluationEngine);
					if (compiledExpression != null) {
						evaluationEngine.evaluateExpression(compiledExpression, objectValue, thread, evaluationListener, DebugEvent.EVALUATION_IMPLICIT, false);
						return;
					}
				} catch (DebugException e) {
					DebugUIPlugin.log(e);
					return;
				}
			}
		}
		try {
			evaluationListener.valueToString(value);
		} catch (DebugException e) {
			listener.detailComputed(value, e.getStatus().getMessage());
		}
	}
	
	private IJavaProject getJavaProject(IJavaThread thread) {
		ILaunch launch= thread.getLaunch();
		if (launch == null) {
			return null;
		}
		ISourceLocator locator= launch.getSourceLocator();
		if (locator == null)
			return null;
		
		Object sourceElement;
		try {
			IStackFrame frame = thread.getTopStackFrame();
			if (frame == null)
				return null;
			sourceElement= locator.getSourceElement(frame);
		} catch (DebugException e) {
			DebugUIPlugin.log(e);
			return null;
		}
		if (sourceElement instanceof IJavaElement) {
			return ((IJavaElement) sourceElement).getJavaProject();
		}
		if (sourceElement instanceof IResource) {
			IJavaProject project = JavaCore.create(((IResource)sourceElement).getProject());
			if (project.exists()) {
				return project;
			}
		}
		// if no source element, try the project associated with the launch - bug 27837
		ILaunchConfiguration configuration = launch.getLaunchConfiguration();
		if (configuration != null) {
			try {
				return JavaRuntime.getJavaProject(configuration);
			} catch (CoreException e) {
				JDIDebugUIPlugin.log(e);
			}
		}
		return null;
	}
	
	
	
	public boolean hasAssociatedDetailFormatter(IJavaType type) {
		return getAssociatedDetailFormatter(type) != null;
	}
	
	public DetailFormatter getAssociatedDetailFormatter(IJavaType type) {
		String typeName;
		try {
			while (type instanceof IJavaArrayType) {
				type= ((IJavaArrayType)type).getComponentType();
			}
			if (type instanceof IJavaClassType) {
				typeName= type.getName();
			} else {
				return null;
			}
		} catch (DebugException e) {
			return null;
		}
		return (DetailFormatter)fDetailFormattersMap.get(typeName);
	}
	
	public void setAssociatedDetailFormatter(DetailFormatter detailFormatter) {
		fDetailFormattersMap.put(detailFormatter.getTypeName(), detailFormatter);
		savePreference();
	}
	
	
	private void savePreference() {
		Collection valuesList= fDetailFormattersMap.values();
		String[] values= new String[valuesList.size() * 3];
		int i= 0;
		for (Iterator iter= valuesList.iterator(); iter.hasNext();) {
			DetailFormatter detailFormatter= (DetailFormatter) iter.next();
			values[i++]= detailFormatter.getTypeName();
			values[i++]= detailFormatter.getSnippet().replace(',','\u0000');
			values[i++]= detailFormatter.isEnabled() ? JavaDetailFormattersPreferencePage.DETAIL_FORMATTER_IS_ENABLED : JavaDetailFormattersPreferencePage.DETAIL_FORMATTER_IS_DISABLED;
		}
		String pref = JavaDebugOptionsManager.serializeList(values);
		JDIDebugUIPlugin.getDefault().getPreferenceStore().setValue(IJDIPreferencesConstants.PREF_DETAIL_FORMATTERS_LIST, pref);
		JDIDebugUIPlugin.getDefault().savePluginPreferences();
	}
	/**
	 * Return the detail formatter (code snippet) associate with
	 * the given type or one of its super type.
	 */
	private String getDetailFormatter(IJavaClassType type) throws DebugException {
		if (type == null) {
			return null;
		}
		String typeName= type.getName();
		if (fDetailFormattersMap.containsKey(typeName)) {
			DetailFormatter detailFormatter= (DetailFormatter)fDetailFormattersMap.get(typeName);
			if (detailFormatter.isEnabled()) {
				return detailFormatter.getSnippet();
			}
		}
		return getDetailFormatter(type.getSuperclass());
	}
	
	/**
	 * Return the compiled expression which corresponds to the code formatter associated
	 * with the type of the given object.
	 * The code snippet is compiled in the context of the given object.
	 */
	private ICompiledExpression getCompiledExpression(IJavaObject javaObject, JDIDebugTarget debugTarget, IAstEvaluationEngine evaluationEngine) throws DebugException {
		IJavaClassType type= (IJavaClassType)javaObject.getJavaType();
		String typeName= type.getName();
		Key key= new Key(typeName, debugTarget);
		if (fCacheMap.containsKey(key)) {
			return (ICompiledExpression) fCacheMap.get(key);
		}
		String snippet= getDetailFormatter(type);
		if (snippet != null) {
			ICompiledExpression res= evaluationEngine.getCompiledExpression(snippet, javaObject);
			fCacheMap.put(key, res);
			return res;
		}
		return null;
	}
	
	/**
	 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(PropertyChangeEvent)
	 */
	public void propertyChange(PropertyChangeEvent event) {
		if (event.getProperty().equals(IJDIPreferencesConstants.PREF_DETAIL_FORMATTERS_LIST)) {
			populateDetailFormattersMap();
			fCacheMap.clear();
		}
	}
	/**
	 * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(DebugEvent[])
	 */
	public void handleDebugEvents(DebugEvent[] events) {
		for (int i = 0; i < events.length; i++) {
			DebugEvent event = events[i];
			if (event.getSource() instanceof JDIDebugTarget && event.getKind() == DebugEvent.TERMINATE) {
				deleteCacheForTarget((JDIDebugTarget) event.getSource());
			}	
		}
	}
	
	/**
	 * @see org.eclipse.debug.core.ILaunchesListener#launchesAdded(ILaunch[])
	 */
	public void launchesAdded(ILaunch[] launches) {
	}
	
	/**
	 * @see org.eclipse.debug.core.ILaunchesListener#launchesChanged(ILaunch[])
	 */
	public void launchesChanged(ILaunch[] launches) {
	}
	
	/**
	 * @see org.eclipse.debug.core.ILaunchesListener#launchesRemoved(ILaunch[])
	 */
	public void launchesRemoved(ILaunch[] launches) {
		for (int i = 0; i < launches.length; i++) {
			ILaunch launch = launches[i];
			IDebugTarget[] debugTargets= launch.getDebugTargets();
			for (int j = 0; j < debugTargets.length; j++) {
				if (debugTargets[j] instanceof JDIDebugTarget) {
					deleteCacheForTarget((JDIDebugTarget)debugTargets[j]);		
				}
			}
		}
	}
	
	/**
	 * Remove from the cache compiled expression associated with
	 * the given debug target.
	 * 
	 * @param debugTarget 
	 */
	private synchronized void deleteCacheForTarget(JDIDebugTarget debugTarget) {
		for (Iterator iter= fCacheMap.keySet().iterator(); iter.hasNext();) {
			Key key= (Key) iter.next();
			if ((key).fDebugTarget == debugTarget) {
				iter.remove();
			}
		}
	}
	
	/**
	 * Object used as the key in the cache map for associate a compiled
	 * expression with a pair type name/debug target
	 */
	static private class Key {
		private String fTypeName;
		private JDIDebugTarget fDebugTarget;
		
		Key(String typeName, JDIDebugTarget debugTarget) {
			fTypeName= typeName;
			fDebugTarget= debugTarget;
		}
		
		public boolean equals(Object obj) {
			if (obj instanceof Key) {
				Key key= (Key) obj;
				return fTypeName != null && fDebugTarget != null && fTypeName.equals(key.fTypeName) && fDebugTarget.equals(key.fDebugTarget);
			}
			return false;
		}
		
		public int hashCode() {
			return fTypeName.hashCode() / 2 + fDebugTarget.hashCode() / 2;
		}
	}
	
	/**
	 * Listener use to manage the result of the formatter.
	 * Utilise the 'standart' pretty printer methods to return the result.
	 */
	static private class EvaluationListener implements IEvaluationListener {
		
		/**
		 * The selector of <code>java.lang.Object#toString()</code>,
		 * used to evaluate 'toString()' for displaying details of values.
		 */
		private static final String fgToString= "toString"; //$NON-NLS-1$
		
		
		/**
		 * The signature of <code>java.lang.Object#toString()</code>,
		 * used to evaluate 'toString()' for displaying details of values.
		 */
		private static final String fgToStringSignature= "()Ljava/lang/String;"; //$NON-NLS-1$
		
		private IJavaValue fValue;
		
		private IValueDetailListener fListener;
		
		private IJavaThread fThread;
		
		public EvaluationListener(IJavaValue value, IJavaThread thread, IValueDetailListener listener) {
			fValue= value;
			fThread= thread;
			fListener= listener;
		}
		
		public void evaluationComplete(IEvaluationResult result) {
			if (result.hasErrors()) {
				StringBuffer error= new StringBuffer(DebugUIMessages.getString("JavaDetailFormattersManager.Detail_formatter_error___1")); //$NON-NLS-1$
				DebugException exception= result.getException();
				if (exception != null) {
					Throwable throwable= exception.getStatus().getException();
					error.append("\n\t\t"); //$NON-NLS-1$
					if (throwable instanceof InvocationException) {
						error.append(MessageFormat.format(DebugUIMessages.getString("JavaDetailFormattersManager.An_exception_occurred__{0}_3"), new String[] {((InvocationException) throwable).exception().referenceType().name()})); //$NON-NLS-1$
					} else {
						error.append(exception.getStatus().getMessage());
					}
				} else {
					String[] errors= result.getErrorMessages();
					for (int i= 0, length= errors.length; i < length; i++) {
						error.append("\n\t\t").append(errors[i]); //$NON-NLS-1$
					}
				}
				fListener.detailComputed(fValue, error.toString());
			} else {
				try {
					valueToString(result.getValue());
				} catch (DebugException e) {
					fListener.detailComputed(fValue, e.getStatus().getMessage());
				}
			}
		}
		
		public void valueToString(final IJavaValue objectValue) throws DebugException {
			IEvaluationRunnable eval = new IEvaluationRunnable() {
				public void run(IJavaThread thread, IProgressMonitor monitor) throws DebugException {
					StringBuffer result= new StringBuffer();
					if (objectValue.getSignature() == null) {
						// no need to spawn a thread for a null fValue
						result.append(DebugUIMessages.getString("JavaDetailFormattersManager.null")); //$NON-NLS-1$
					} else if (objectValue instanceof IJavaPrimitiveValue) {
						// no need to spawn a thread for a primitive value
						appendJDIPrimitiveValueString(result, objectValue);
					} else if (fThread == null || !fThread.isSuspended()) {
						// no thread available
						result.append(DebugUIMessages.getString("JavaDetailFormattersManager.no_suspended_threads")); //$NON-NLS-1$
						appendJDIValueString(result, objectValue);
					} else if (objectValue instanceof IJavaArray) {
						appendArrayDetail(result, (IJavaArray) objectValue);
					} else if (objectValue instanceof IJavaObject) {
						appendObjectDetail(result, (IJavaObject) objectValue);
					} else {
						appendJDIValueString(result, objectValue);
					}
					fListener.detailComputed(fValue, result.toString());
				}
			};
			fThread.runEvaluation(eval, null, DebugEvent.EVALUATION_IMPLICIT, false);
		}
		
		/*
		 * Tries to use Arrays.asList() on target because List has a better toString() to 
		 * display. If not possible (or if array is of a primitive type), appendArrayDetailIndividually
		 * is called.
		 */
		protected void appendArrayDetail(StringBuffer result, IJavaArray arrayValue) throws DebugException {
			IJavaType componentType = null;
			try {
				IJavaArrayType javaArrayType = (IJavaArrayType) arrayValue.getJavaType();
				componentType = javaArrayType.getComponentType();
			} catch (DebugException de) {
				JDIDebugUIPlugin.log(de);
				result.append(de.getStatus().getMessage());
				return;	
			}
			
			if (!(componentType instanceof IJavaReferenceType)) {
				//if it is an array of primatives, cannot use Arrays.asList()
				appendArrayDetailIndividually(result, arrayValue);
				return;
			}
			
			IJavaDebugTarget target = (IJavaDebugTarget) arrayValue.getDebugTarget();
			
			//Load java.util.Arrays
			IJavaType[] types;
			try {
				types = target.getJavaTypes("java.lang.Class"); //$NON-NLS-1$
			} catch (DebugException de) {
				types = null;
			}
			
			if (types != null && types.length >0) {
				try {
					IJavaClassType type = (IJavaClassType) types[0];
					IJavaValue arg = target.newValue("java.util.Arrays"); //$NON-NLS-1$
					type.sendMessage("forName", "(Ljava/lang/String;)Ljava/lang/Class;", new IJavaValue[] {arg}, fThread);  //$NON-NLS-1$//$NON-NLS-2$
				} catch (DebugException de) {
					//java.util.Arrays didn't load properly. Can't use Arrays.asList()
					appendArrayDetailIndividually(result, arrayValue);
				}
			} else {
				//didn't get java.lang.Class, can't load java.utils.Arrays.
				appendArrayDetailIndividually(result, arrayValue);
			}
			
			types = null;
			types = target.getJavaTypes("java.util.Arrays"); //$NON-NLS-1$
			if (types != null && types.length >0) {
				IJavaClassType type = (IJavaClassType) types[0];
				IJavaObject javaObject;
				try {
					//execute Arrays.asList() on target
					javaObject = (IJavaObject) type.sendMessage("asList", "([Ljava/lang/Object;)Ljava/util/List;", new IJavaValue[] {arrayValue}, fThread); //$NON-NLS-1$ //$NON-NLS-2$
				} catch (DebugException de) {
					//asList() failed.
					appendArrayDetailIndividually(result, arrayValue);
					return;
				}
				appendObjectDetail(result, javaObject);
			} else {
				// didn't get java.util.Arrays. Can't use asList() 
				appendArrayDetailIndividually(result, arrayValue);
			}
		}
		
		/*
		 * Gets all values in array and appends the toString() if it is an array of Objects or the value if primative.
		 * NB - this method is only called by appendArrayDetail which first tries to use Arrays.asList() to minimize
		 * toString() calls on remote target (ie one call to List.toString() instead of one call per item in the array). 
		 */
		private void appendArrayDetailIndividually(StringBuffer result, IJavaArray arrayValue) throws DebugException {
			result.append('[');
			IJavaValue[] arrayValues;
			try {				
				arrayValues= arrayValue.getValues();				
			} catch (DebugException de) {
				JDIDebugUIPlugin.log(de);
				result.append(de.getStatus().getMessage());
				return;
			}
			for (int i= 0; i < arrayValues.length; i++) {
				IJavaValue value= arrayValues[i];
				if (value instanceof IJavaArray) {
					appendArrayDetail(result, (IJavaArray) value);
				} else if (value instanceof IJavaObject) {
					appendObjectDetail(result, (IJavaObject) value);
				} else {
					appendJDIValueString(result, value);
				}
				if (i < arrayValues.length - 1) {
					result.append(',');
					result.append(' ');
				}
			}
			result.append(']');	
		}
		
		protected void appendJDIPrimitiveValueString(StringBuffer result, IJavaValue value) throws DebugException {
			result.append(value.getValueString());
		}
		
		
		protected void appendJDIValueString(StringBuffer result, IJavaValue value) throws DebugException {
			result.append(value.getValueString());
		}
		
		
		protected void appendObjectDetail(StringBuffer result, IJavaObject objectValue) throws DebugException {
			IJavaValue toStringValue= objectValue.sendMessage(EvaluationListener.fgToString, EvaluationListener.fgToStringSignature, null, fThread, false);
			if (toStringValue == null) {
				result.append(DebugUIMessages.getString("JavaDetailFormattersManager.<unknown>")); //$NON-NLS-1$
			} else {
				appendJDIValueString(result, toStringValue);
			}
		}
		
		
		
	}
	
	/**
	 * (non java-doc)
	 * Remove the provided <code>detailFormatter</code> from the map
	 * @param detailFormatter
	 */
	public void removeAssociatedDetailFormatter(DetailFormatter detailFormatter) {
		fDetailFormattersMap.remove(detailFormatter.getTypeName());
		savePreference();
	}
	
}
