/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *     QNX Software Systems - Mikhail Khodjaiants - Registers View (Bug 53640)
 *     Valentin Ciocoi - Bug 414994 Guard against out of bounds exception when handling escaped characters in DefaultLabelProvider
 *******************************************************************************/
package org.eclipse.debug.internal.ui;


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

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchDelegate;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IDisconnect;
import org.eclipse.debug.core.model.IExpression;
import org.eclipse.debug.core.model.ILineBreakpoint;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IRegister;
import org.eclipse.debug.core.model.IRegisterGroup;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.ITerminate;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.core.model.IWatchExpression;
import org.eclipse.debug.core.model.IWatchpoint;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutExtension;
import org.eclipse.debug.internal.ui.views.variables.IndexedVariablePartition;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.model.IWorkbenchAdapter;

public class DefaultLabelProvider implements ILabelProvider {

	/**
	 * Maps image descriptors to images.
	 */
	private Map<ImageDescriptor, Image> fImages = new HashMap<>();

	/**
	 * @see ILabelProvider#getImage(Object)
	 */
	@Override
	public Image getImage(Object element) {
		String key= getImageKey(element);
		if (key == null && element instanceof ILaunch) {
			return null;
		}
		if (key == null && element instanceof IAdaptable) {
			IWorkbenchAdapter de= ((IAdaptable) element).getAdapter(IWorkbenchAdapter.class);
			if (de != null) {
				ImageDescriptor descriptor= de.getImageDescriptor(element);
				if( descriptor != null) {
					return getImage(descriptor);
				}
			}
			return null;
		}
		if(element instanceof LaunchShortcutExtension) {
			return getImage(((LaunchShortcutExtension)element).getImageDescriptor());
		}
		return DebugPluginImages.getImage(key);
	}

	/**
	 * Returns an image created from the given image descriptor or <code>null</code>.
	 * Caches and reuses images.
	 *
	 * @param descriptor image descriptor
	 * @return image or <code>null</code>
	 */
	private Image getImage(ImageDescriptor descriptor) {
		Image image = fImages.get(descriptor);
		if (image != null) {
			return image;
		}
		image = descriptor.createImage();
		if (image != null) {
			fImages.put(descriptor, image);
		}
		return image;
	}

	/**
	 * Returns the key (<code>String</code>) of the default image
	 * appropriate for the given element or <code>null</code>
	 * if no default image is defined.
	 */
	public String getImageKey(Object element) {
		if (element instanceof IDebugElement) {
			// Group elements into debug elements and non-debug elements
			// to reduce the number of instanceof checks performed
			if (element instanceof IRegister) {
				return IDebugUIConstants.IMG_OBJS_REGISTER;
			} else if (element instanceof IRegisterGroup) {
				return IDebugUIConstants.IMG_OBJS_REGISTER_GROUP;
			} else if (element instanceof IVariable || element instanceof IValue) {
				if (element instanceof IndexedVariablePartition) {
					return IInternalDebugUIConstants.IMG_OBJS_ARRAY_PARTITION;
				}
				return IDebugUIConstants.IMG_OBJS_VARIABLE;
			} else if (element instanceof IStackFrame) {
				if (((IStackFrame)element).getThread().isSuspended()) {
					return IDebugUIConstants.IMG_OBJS_STACKFRAME;
				}
				return IDebugUIConstants.IMG_OBJS_STACKFRAME_RUNNING;
			} else if (element instanceof IThread) {
				IThread thread = (IThread)element;
				if (thread.isSuspended()) {
					return IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED;
				} else if (thread.isTerminated()) {
					return IDebugUIConstants.IMG_OBJS_THREAD_TERMINATED;
				} else {
					return IDebugUIConstants.IMG_OBJS_THREAD_RUNNING;
				}
			} else if (element instanceof IDebugTarget) {
				IDebugTarget target= (IDebugTarget) element;
				if (target.isTerminated() || target.isDisconnected()) {
					return IDebugUIConstants.IMG_OBJS_DEBUG_TARGET_TERMINATED;
				} else if (target.isSuspended()) {
					return IDebugUIConstants.IMG_OBJS_DEBUG_TARGET_SUSPENDED;
				} else {
					return IDebugUIConstants.IMG_OBJS_DEBUG_TARGET;
				}
			} else if (element instanceof IExpression) {
				return IDebugUIConstants.IMG_OBJS_EXPRESSION;
			}
		} else {
			if (element instanceof IMarker) {
				return getMarkerImageKey((IMarker)element);
			} else if (element instanceof IBreakpoint) {
				return getBreakpointImageKey((IBreakpoint)element);
			} else if (element instanceof IProcess) {
				if (((IProcess) element).isTerminated()) {
					return IDebugUIConstants.IMG_OBJS_OS_PROCESS_TERMINATED;
				}
				return IDebugUIConstants.IMG_OBJS_OS_PROCESS;
			} else if (element instanceof ILaunch) {
				// determine the image from the launch config type
				ILaunch launch= (ILaunch)element;
				ILaunchConfiguration configuration = launch.getLaunchConfiguration();
				if (configuration != null) {
					try {
						return configuration.getType().getIdentifier();
					} catch (CoreException e) {
						DebugUIPlugin.log(e);
						return null;
					}
				}
				// if no config, use the old "mode" way
				if (launch.getLaunchMode().equals(ILaunchManager.DEBUG_MODE)) {
					return IDebugUIConstants.IMG_OBJS_LAUNCH_DEBUG;
				} else if (launch.isTerminated()) {
					return IDebugUIConstants.IMG_OBJS_LAUNCH_RUN_TERMINATED;
				} else {
					return IDebugUIConstants.IMG_OBJS_LAUNCH_RUN;
				}
			} else if (element instanceof ILaunchConfigurationType) {
				return ((ILaunchConfigurationType)element).getIdentifier();
			} else if (element instanceof ILaunchConfiguration) {
				try {
					return ((ILaunchConfiguration)element).getType().getIdentifier();
				} catch (CoreException e) {
					DebugUIPlugin.log(e);
					return null;
				}
			}
		}
		return null;
	}

	/**
	 * @see ILabelProvider#getText(Object)
	 */
	@Override
	public String getText(Object element) {
		StringBuilder label= new StringBuilder();
		try {
			// Group elements into debug elements and non-debug elements
			// to reduce the number of instanceof checks performed
			if (element instanceof IDebugElement) {
				if (element instanceof IStackFrame) {
					label.append(((IStackFrame)element).getName());
				} else if (element instanceof IndexedVariablePartition) {
					label.append(((IndexedVariablePartition)element).getName());
				} else if (element instanceof IVariable) {
					label.append(getVariableText((IVariable)element));
				} else if (element instanceof IThread) {
					label.append(((IThread)element).getName());
				} else if (element instanceof IDebugTarget) {
					label.append((((IDebugTarget)element).getName()));
				} else if (element instanceof IExpression) {
					label.append(getExpressionText((IExpression)element));
				} else if (element instanceof IRegisterGroup) {
					label.append(getRegisterGroupText((IRegisterGroup)element));
				} else if (element instanceof IValue) {
					label.append(((IValue)element).getValueString());
				}
			} else {
				if (element instanceof IMarker) {
					label.append(getMarkerText((IMarker) element));
				} else if (element instanceof IBreakpoint) {
					label.append(getBreakpointText((IBreakpoint)element));
				} else if (element instanceof IProcess) {
					label.append(((IProcess) element).getLabel());
				} else if (element instanceof ILaunch) {
					label.append(getLaunchText((ILaunch) element));
				} else if (element instanceof ILaunchConfiguration) {
					label.append(((ILaunchConfiguration)element).getName());
				} else if (element instanceof ILaunchConfigurationType) {
					label.append(((ILaunchConfigurationType)element).getName());
				} else if(element instanceof ILaunchDelegate) {
					ILaunchDelegate delegate = (ILaunchDelegate) element;
					String name = delegate.getName();
					if(name == null) {
						name = delegate.getContributorName();
					}
					label.append(name);
				} else if(element instanceof LaunchShortcutExtension) {
					label.append(((LaunchShortcutExtension)element).getLabel());
				} else if (element instanceof String) {
					label.append(element);
				} else {
					label.append(getAdapterLabel(element));
				}
			}
			if (element instanceof ITerminate) {
				if (((ITerminate) element).isTerminated()) {
					String terminatedMessage= null;
					if (element instanceof IProcess) {
						IProcess process = (IProcess)element;
						int exit = process.getExitValue();
						terminatedMessage = MessageFormat.format(DebugUIMessages.DefaultLabelProvider_16, new Object[] { Integer.valueOf(exit).toString() });
					} else {
						terminatedMessage= DebugUIMessages.DefaultLabelProvider_1;
					}
					label.insert(0, terminatedMessage);
				}
			} else if (element instanceof IDisconnect) {
				if (((IDisconnect) element).isDisconnected()) {
					label.insert(0, DebugUIMessages.DefaultLabelProvider__disconnected__1);
				}
			}
		} catch (DebugException e) {
			DebugUIPlugin.log(e);
			label.append(DebugUIMessages.DefaultLabelProvider__unknown__1);
		}
		return label.toString();
	}

	/**
	 * Returns default label for a breakpoint.
	 *
	 * @param breakpoint
	 * @return default label for a breakpoint
	 */
	private String getBreakpointText(IBreakpoint breakpoint) {
		IResource resource = breakpoint.getMarker().getResource();
		StringBuilder label = new StringBuilder();
		if (resource != null) {
			label.append(resource.getName());
		}
		if (breakpoint instanceof ILineBreakpoint) {
			try {
				int lineNumber = ((ILineBreakpoint)breakpoint).getLineNumber();
				label.append(MessageFormat.format(DebugUIMessages.DefaultLabelProvider_17, new Object[] { Integer.toString(lineNumber) }));
			} catch (CoreException e) {
			}
		}
		return label.toString();
	}

	public String getAdapterLabel(Object object) {
		if (object instanceof IAdaptable) {
			IWorkbenchAdapter de= ((IAdaptable) object).getAdapter(IWorkbenchAdapter.class);
			if (de != null) {
				return de.getLabel(object);
			}
		}
		return DebugUIMessages.DefaultLabelProvider__unknown__1;
	}

	/**
	 * Used to render launch history items in the re-launch drop downs
	 */
	protected String getLaunchText(ILaunch launch) {
		if (launch.getLaunchConfiguration() == null || (!launch.getLaunchConfiguration().exists() && !launch.getLaunchConfiguration().isWorkingCopy())) {
			return DebugUIMessages.DefaultLabelProvider__unknown__1;
		}
		// new launch configuration
		ILaunchConfiguration config = launch.getLaunchConfiguration();
		StringBuilder buff= new StringBuilder(config.getName());
		buff.append(" ["); //$NON-NLS-1$
		try {
			buff.append(config.getType().getName());
		} catch (CoreException e) {
			DebugUIPlugin.log(e);
		}
		buff.append("]"); //$NON-NLS-1$
		return buff.toString();
	}

	protected String getExpressionText(IExpression expression) {
		if (expression instanceof IWatchExpression) {
			return getWatchExpressionText((IWatchExpression) expression);
		}
		StringBuilder buffer= new StringBuilder(expression.getExpressionText());
		String valueString= null;
		IValue value= expression.getValue();
		if (value != null) {
			try {
				valueString= value.getValueString();
			} catch (DebugException de) {
				DebugUIPlugin.log(de);
			}
		}
		if (valueString != null && valueString.length() > 0) {
			buffer.append("= "); //$NON-NLS-1$
			buffer.append(valueString);
		}
		return buffer.toString();
	}

	/**
	 * @param expression
	 * @return
	 */
	protected String getWatchExpressionText(IWatchExpression expression) {
		StringBuilder result= new StringBuilder();

		String snippet = expression.getExpressionText().trim();
		StringBuilder snippetBuffer = new StringBuilder();
		if (snippet.length() > 30){
			snippetBuffer.append(snippet.substring(0, 15));
			snippetBuffer.append(DebugUIMessages.DefaultLabelProvider_0);
			snippetBuffer.append(snippet.substring(snippet.length() - 15));
		} else {
			snippetBuffer.append(snippet);
		}
		snippet = snippetBuffer.toString().replaceAll("[\n\r\t]+", " ");  //$NON-NLS-1$//$NON-NLS-2$

		result.append('"');
		result.append(snippet);
		result.append('"');

		if (expression.isPending()) {
			result.append(DebugUIMessages.DefaultLabelProvider_12);
		} else if (expression.hasErrors()) {
			result.append(DebugUIMessages.DefaultLabelProvider_13);
		} else {
			IValue value= expression.getValue();
			if (value != null) {
				String valueString= DebugUIPlugin.getModelPresentation().getText(value);
				if (valueString.length() > 0) {
					result.append(" = ").append(valueString); //$NON-NLS-1$
				}
			}
		}
		if (!expression.isEnabled()) {
			result.append(DebugUIMessages.DefaultLabelProvider_15);
		}
		return result.toString();
	}

	protected String getVariableText(IVariable variable) {
		StringBuilder buffer= new StringBuilder();
		try {
			IValue value = variable.getValue();
			buffer.append(variable.getName());
			buffer.append(" = "); //$NON-NLS-1$
			buffer.append(value.getValueString());
		} catch (DebugException de) {
			DebugUIPlugin.log(de);
		}
		return buffer.toString();
	}

	protected String getRegisterGroupText(IRegisterGroup registerGroup) {
		StringBuilder buffer= new StringBuilder();
		try {
			buffer.append(registerGroup.getName());
		} catch (DebugException de) {
			DebugUIPlugin.log(de);
		}
		return buffer.toString();
	}

	protected String getMarkerText(IMarker marker) {
		try {
			if (marker.exists() && marker.isSubtypeOf(IBreakpoint.BREAKPOINT_MARKER)) {
				return DebugUIMessages.DefaultLabelProvider_Breakpoint_1;
			}
		} catch (CoreException e) {
			DebugUIPlugin.log(e);
		}
		return IInternalDebugCoreConstants.EMPTY_STRING;
	}

	protected String getMarkerImageKey(IMarker marker) {
		try {
			IBreakpoint breakpoint= DebugPlugin.getDefault().getBreakpointManager().getBreakpoint(marker);
			if (breakpoint != null && marker.exists()) {
				if (breakpoint.isEnabled()) {
					return IDebugUIConstants.IMG_OBJS_BREAKPOINT;
				}
				return IDebugUIConstants.IMG_OBJS_BREAKPOINT_DISABLED;
			}
		} catch (CoreException e) {
		}
		return null;
	}

	protected String getBreakpointImageKey(IBreakpoint breakpoint) {
		if (breakpoint != null && breakpoint.getMarker().exists()) {
			try {
				boolean enabled = breakpoint.isEnabled();
				if (breakpoint instanceof IWatchpoint) {
					IWatchpoint watchpoint = (IWatchpoint) breakpoint;
					if (watchpoint.isAccess()) {
						if (watchpoint.isModification()) {
							//access and modification
							if (enabled) {
								return IDebugUIConstants.IMG_OBJS_WATCHPOINT;
							}
							return IDebugUIConstants.IMG_OBJS_WATCHPOINT_DISABLED;
						}
						if (enabled) {
							return IDebugUIConstants.IMG_OBJS_ACCESS_WATCHPOINT;
						}
						return IDebugUIConstants.IMG_OBJS_ACCESS_WATCHPOINT_DISABLED;
					} else if (watchpoint.isModification()) {
						if (enabled) {
							return IDebugUIConstants.IMG_OBJS_MODIFICATION_WATCHPOINT;
						}
						return IDebugUIConstants.IMG_OBJS_MODIFICATION_WATCHPOINT_DISABLED;
					} else {
						//neither access nor modification
						return IDebugUIConstants.IMG_OBJS_WATCHPOINT_DISABLED;
					}
				}
				if (enabled) {
					return IDebugUIConstants.IMG_OBJS_BREAKPOINT;
				}
				return IDebugUIConstants.IMG_OBJS_BREAKPOINT_DISABLED;
			} catch (CoreException e) {
			}
		}
		return null;
	}

	/**
	 * @see IBaseLabelProvider#addListener(ILabelProviderListener)
	 */
	@Override
	public void addListener(ILabelProviderListener listener) {
	}

	/**
	 * @see IBaseLabelProvider#dispose()
	 */
	@Override
	public void dispose() {
		for (Image image : fImages.values()) {
			image.dispose();
		}
		fImages.clear();
	}

	/**
	 * @see IBaseLabelProvider#isLabelProperty(Object, String)
	 */
	@Override
	public boolean isLabelProperty(Object element, String property) {
		return false;
	}

	/**
	 * @see IBaseLabelProvider#removeListener(ILabelProviderListener)
	 */
	@Override
	public void removeListener(ILabelProviderListener listener) {
	}

	/**
	 * Returns the given string with special chars in escaped sequences.
	 *
	 * @param label
	 * @return the given string with special chars in escaped sequences
	 * @since 3.3
	 */
	public static String escapeSpecialChars(String string) {
		if (string == null) {
			return null;
		}
		StringBuilder escaped = new StringBuilder();
		for (int i = 0; i < string.length(); i++) {
			char c = string.charAt(i);
			switch (c) {
				case '\b':
					escaped.append("\\b"); //$NON-NLS-1$
					break;
				case '\f':
					escaped.append("\\f"); //$NON-NLS-1$
					break;
				case '\n':
					escaped.append("\\n"); //$NON-NLS-1$
					break;
				case '\r':
					escaped.append("\\r"); //$NON-NLS-1$
					break;
				case '\t':
					escaped.append("\\t"); //$NON-NLS-1$
					break;
				case '\\':
					escaped.append("\\\\"); //$NON-NLS-1$
					break;
				default:
					escaped.append(c);
					break;
			}
		}
		return escaped.toString();
	}

	/**
	 * Returns the string with escaped sequences replaced with single chars.
	 *
	 * @param string
	 * @return the string with escaped sequences replaced with single chars
	 * @since 3.3
	 */
	public static String encodeEsacpedChars(String string) {
		if (string == null) {
			return null;
		}
		StringBuilder encoded = new StringBuilder();
		if (string.length() == 1) {
			return string;
		}
		for (int i = 0; i < string.length(); i++) {
			char c = string.charAt(i);
			if (c == '\\' && (i + 1 < string.length())) {
				switch (string.charAt(i+1)) {
					case 'b':
						c= '\b';
						i++;
						break;
					case 'f':
						c= '\f';
						i++;
						break;
					case 'n':
						c= '\n';
						i++;
						break;
					case 'r':
						c= '\r';
						i++;
						break;
					case 't':
						c= '\t';
						i++;
						break;
					case '\'':
						c= '\'';
						i++;
						break;
					case '\\':
						c= '\\';
						i++;
						break;
					default :
						break;
				}
			}
			encoded.append(c);
		}
		return encoded.toString();
	}
}

