/*******************************************************************************
 * 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
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.breakpoints;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.debug.core.IJavaBreakpoint;
import org.eclipse.jdt.debug.core.IJavaClassPrepareBreakpoint;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.internal.debug.ui.BreakpointUtils;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.ui.IJavaElementSearchConstants;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.dialogs.SelectionDialog;

/**
 * The workbench action for creating a class load breakpoint
 */
public class AddClassPrepareBreakpointAction implements IWorkbenchWindowActionDelegate {

    /**
     * the current workbench window
     */
    private IWorkbenchWindow workbenchWindow;

    /**
     * Creates the breakpoints from the array of returned selections
     * @param selection the selections form the dialog
     * @since 3.2
     */
    private void createBreakpoints(final Object[] selection) {
    	try {
			for (Object a : selection) {
				final IType type = (IType) a;
				final IResource resource = BreakpointUtils.getBreakpointResource(type);
				final Map<String, Object> map = new HashMap<>(10);
				BreakpointUtils.addJavaBreakpointAttributes(map, type);
				int kind = IJavaClassPrepareBreakpoint.TYPE_CLASS;
				if (!type.isClass()) {
					kind = IJavaClassPrepareBreakpoint.TYPE_INTERFACE;
				}
				boolean exists = false;
				for (IBreakpoint b : DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(JDIDebugModel.getPluginIdentifier())) {
					IJavaBreakpoint breakpoint = (IJavaBreakpoint) b;
					if (breakpoint instanceof IJavaClassPrepareBreakpoint) {
						String typeName = breakpoint.getTypeName();
						if (typeName != null && typeName.equals(type.getFullyQualifiedName())) {
							exists = true;
							break;
						}
					}
				}
				if (!exists) {
					ISourceRange range = type.getNameRange();
					int start = -1;
					int end = -1;
					if (range != null) {
						start = range.getOffset();
						end = start + range.getLength();
					}
					final int finalKind = kind;
					final int finalStart = start;
					final int finalEnd = end;
					new Job(BreakpointMessages.AddClassPrepareBreakpointAction_2) {
						@Override
						protected IStatus run(IProgressMonitor monitor) {
							try {
								JDIDebugModel.createClassPrepareBreakpoint(resource, type.getFullyQualifiedName(), finalKind, finalStart, finalEnd, true, map);
								return Status.OK_STATUS;
							} catch (CoreException e) {
								return e.getStatus();
							}
						}

					}.schedule();
				}
			}
	    } catch(CoreException e) {
	    	JDIDebugUIPlugin.statusDialog(e.getStatus());
	    }
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
     */
    @Override
	public void run(IAction action) {
        Shell shell = JDIDebugUIPlugin.getActiveWorkbenchShell();
        SelectionDialog dialog = null;
        try {
        	dialog = JavaUI.createTypeDialog(shell, workbenchWindow,
        									 SearchEngine.createWorkspaceScope(),
        									 IJavaElementSearchConstants.CONSIDER_CLASSES,
        									 true, "", null); //$NON-NLS-1$
            dialog.setTitle(BreakpointMessages.AddClassPrepareBreakpointAction_0);
            dialog.setMessage(BreakpointMessages.AddClassPrepareBreakpointAction_1);
            if (dialog.open() == IDialogConstants.OK_ID) {
               createBreakpoints(dialog.getResult());
            }
        } catch (CoreException e) {JDIDebugUIPlugin.log(e);}
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
     */
    @Override
	public void selectionChanged(IAction action, ISelection selection) {}

    /* (non-Javadoc)
     * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
     */
    @Override
	public void dispose() {
        workbenchWindow = null;
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
     */
    @Override
	public void init(IWorkbenchWindow window) {
        workbenchWindow = window;
    }
}
