/*******************************************************************************
 * 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<>();
					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<>();

		try {
			// collect names in type hierarchy
			List<String> superTypeNames = new ArrayList<>();
			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;
	}

}
