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

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.internal.ui.AbstractDebugCheckboxSelectionDialog;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.jdt.debug.core.IJavaBreakpoint;
import org.eclipse.jdt.debug.core.IJavaClassType;
import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint;
import org.eclipse.jdt.debug.core.IJavaFieldVariable;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaType;
import org.eclipse.jdt.debug.core.IJavaVariable;
import org.eclipse.jdt.debug.core.IJavaWatchpoint;
import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants;
import org.eclipse.jdt.internal.debug.ui.IJavaDebugHelpContextIds;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;

/**
 * Action to associate an object with one or more breakpoints.
 */
public class InstanceFiltersAction extends ObjectActionDelegate {
	
	/**
	 * Dialog that allows the user to select one or more breakpoints that should be restricted
	 * to a specific object instance.
	 */
	class InstanceFilterDialog extends AbstractDebugCheckboxSelectionDialog {
		
		private Object fInput;
		private String fMessage;
		private IBaseLabelProvider fLabelProvider;
		
		public InstanceFilterDialog(Shell parentShell, Object input, IBaseLabelProvider labelProvider, String message){
			super(parentShell);
			fInput = input;
			fMessage = message;
			fLabelProvider = labelProvider;
			setShellStyle(getShellStyle() | SWT.RESIZE);
			setShowSelectAllButtons(true);
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.AbstractDebugCheckboxSelectionDialog#isValid()
		 */
		@Override
		protected boolean isValid() {
			return true;
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.launchConfigurations.AbstractDebugSelectionDialog#getDialogSettingsId()
		 */
		@Override
		protected String getDialogSettingsId() {
			return IJavaDebugUIConstants.PLUGIN_ID + ".INSTANCE_FILTERS_ACTION_DIALOG"; //$NON-NLS-1$
		}

		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.launchConfigurations.AbstractDebugSelectionDialog#getHelpContextId()
		 */
		@Override
		protected String getHelpContextId() {
			return IJavaDebugHelpContextIds.INSTANCE_BREAKPOINT_SELECTION_DIALOG;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.launchConfigurations.AbstractDebugSelectionDialog#getViewerInput()
		 */
		@Override
		protected Object getViewerInput() {
			return fInput;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.launchConfigurations.AbstractDebugSelectionDialog#getViewerLabel()
		 */
		@Override
		protected String getViewerLabel() {
			return fMessage;
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.launchConfigurations.AbstractDebugSelectionDialog#getLabelProvider()
		 */
		@Override
		protected IBaseLabelProvider getLabelProvider() {
			return fLabelProvider;
		}
}

	/**
	 * @see org.eclipse.ui.IActionDelegate#run(IAction)
	 */
	@Override
	public void run(IAction action) {
		IStructuredSelection selection = getCurrentSelection();
		if (selection == null || selection.size() > 1) {
			return;
		}
		
		Object o = selection.getFirstElement();
		if (o instanceof IJavaVariable) {
			final IJavaVariable var = (IJavaVariable)o;
			try {
				IValue value = var.getValue();
				if (value instanceof IJavaObject) {
					final IJavaObject object = (IJavaObject)value;
					final List<IJavaBreakpoint> breakpoints = getApplicableBreakpoints(var, object);
					final IDebugModelPresentation modelPresentation= DebugUITools.newDebugModelPresentation();
					
					if (breakpoints.isEmpty())
					{
						MessageDialog.openInformation(JDIDebugUIPlugin.getActiveWorkbenchShell(), ActionMessages.InstanceFiltersAction_0, ActionMessages.InstanceFiltersAction_4);
						return;
					}
					
					InstanceFilterDialog dialog = new InstanceFilterDialog(JDIDebugUIPlugin.getActiveWorkbenchShell(), breakpoints, modelPresentation, NLS.bind(ActionMessages.InstanceFiltersAction_1, new String[] {var.getName()})){ 
						@Override
						public void okPressed() {
							// check if breakpoints have already been restricted to other objects.
							Object[] checkBreakpoint= getCheckBoxTableViewer().getCheckedElements();
							for (int k= 0; k < checkBreakpoint.length; k++) {
								IJavaBreakpoint breakpoint= (IJavaBreakpoint) checkBreakpoint[k];
								try {
									IJavaObject[] instanceFilters= breakpoint.getInstanceFilters();
									boolean sameTarget = false;
									for (int i = 0; i < instanceFilters.length; i++) {
										IJavaObject instanceFilter = instanceFilters[i];
										if (instanceFilter.getDebugTarget().equals(object.getDebugTarget())) {
											sameTarget = true;
											break;
										}
									}
									if (sameTarget) {
										MessageDialog messageDialog= new MessageDialog(JDIDebugUIPlugin.getActiveWorkbenchShell(), ActionMessages.InstanceFiltersAction_2, 
											null, NLS.bind(ActionMessages.InstanceFiltersAction_3, new String[] { modelPresentation.getText(breakpoint), var.getName()}), 
											MessageDialog.QUESTION, new String[] { ActionMessages.InstanceFiltersAction_Yes_2, ActionMessages.InstanceFiltersAction_Cancel_3}, // 
											0);
										if (messageDialog.open() == Window.OK) {
											for (int i= 0; i < instanceFilters.length; i++) {
												breakpoint.removeInstanceFilter(instanceFilters[i]);
											}
										} else {
											// if 'cancel', do not close the instance filter dialog
											return;
										}
									}
								} catch (CoreException e) {
									JDIDebugUIPlugin.log(e);
								}
							}
							super.okPressed();
						}
					};
					dialog.setTitle(ActionMessages.InstanceFiltersAction_2); 
					
					// determine initial selection
					List<IJavaBreakpoint> existing = new ArrayList<IJavaBreakpoint>();
					Iterator<IJavaBreakpoint> iter = breakpoints.iterator();
					while (iter.hasNext()) {
						IJavaBreakpoint bp = iter.next();
						IJavaObject[] filters = bp.getInstanceFilters();
						for (int i = 0; i < filters.length; i++) {
							if (filters[i].equals(object)) {
								existing.add(bp);
								break;
							}
						}
					}
					dialog.setInitialSelections(existing.toArray());
					
					if (dialog.open() == Window.OK) {
						Object[] selectedBreakpoints = dialog.getResult();
						if (selectedBreakpoints != null) {
							// add
							for (int i = 0; i < selectedBreakpoints.length; i++) {
								IJavaBreakpoint bp = (IJavaBreakpoint)selectedBreakpoints[i];
								bp.addInstanceFilter(object);
								existing.remove(bp);
							}
							// remove
							iter = existing.iterator();
							while (iter.hasNext()) {
								IJavaBreakpoint bp = iter.next();
								bp.removeInstanceFilter(object);
							}
						}
					}
				} else {
					// only allowed for objects
				}
			} catch (CoreException e) {
				JDIDebugUIPlugin.log(e);
			}
		}
	}
	
	protected List<IJavaBreakpoint> getApplicableBreakpoints(IJavaVariable variable, IJavaObject object) {
		List<IJavaBreakpoint> breakpoints = new ArrayList<IJavaBreakpoint>();
		
		try {
			// collect names in type hierarchy
			List<String> superTypeNames = new ArrayList<String>();
			IJavaType type = object.getJavaType();
			while (type instanceof IJavaClassType) {
				superTypeNames.add(type.getName());
				type = ((IJavaClassType)type).getSuperclass();
			}
			
			IBreakpoint[] allBreakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints();
			for (int i = 0; i < allBreakpoints.length; i++) {
				if (allBreakpoints[i] instanceof IJavaBreakpoint) {
					IJavaBreakpoint jbp = (IJavaBreakpoint)allBreakpoints[i];
					IJavaBreakpoint valid = null;
					if (jbp instanceof IJavaWatchpoint && variable instanceof IJavaFieldVariable) {
						IJavaWatchpoint wp = (IJavaWatchpoint)jbp;
						IJavaFieldVariable fv = (IJavaFieldVariable)variable;
						if (variable.getName().equals(wp.getFieldName()) && fv.getDeclaringType().getName().equals(wp.getTypeName())) {
							valid = wp;
						}
					} else if (superTypeNames.contains(jbp.getTypeName()) || jbp instanceof IJavaExceptionBreakpoint) {
						valid = jbp;
					}
					if (valid != null && valid.supportsInstanceFilters()) {
						breakpoints.add(valid);
					}
				}
			}
		} catch (CoreException e) {
			JDIDebugUIPlugin.log(e);
		}
		 
		return breakpoints;
	}

}
