/*******************************************************************************
 * Copyright (c) 2005, 2012 IBM Corporation and others.
 * All rights reserved. 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.bpel.ui.commands;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.bpel.model.EventHandler;
import org.eclipse.bpel.model.FaultHandler;
import org.eclipse.bpel.model.Flow;
import org.eclipse.bpel.model.Link;
import org.eclipse.bpel.model.PartnerLink;
import org.eclipse.bpel.model.Process;
import org.eclipse.bpel.model.partnerlinktype.PartnerLinkType;
import org.eclipse.bpel.model.util.BPELUtils;
import org.eclipse.bpel.ui.BPELEditor;
import org.eclipse.bpel.ui.Messages;
import org.eclipse.bpel.ui.adapters.IContainer;
import org.eclipse.bpel.ui.adapters.ILabeledElement;
import org.eclipse.bpel.ui.commands.util.AutoUndoCommand;
import org.eclipse.bpel.ui.util.BPELUtil;
import org.eclipse.bpel.ui.util.FlowLinkUtil;
import org.eclipse.bpel.ui.util.ModelHelper;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.wsdl.Definition;

/**
 * Deletes a model object from an IContainer, and removes any references to it
 * from other model objects.
 * 
 * This is more or less the opposite of InsertInContainerCommand.
 * 
 * TODO: simplify this command now that it's an AutoUndoCommand!
 */
public class DeleteChildCommand extends AutoUndoCommand {

	private EObject fChild;
	private EObject fParent;

	IContainer fContainer;

	Resource[] resourcesToModify = null;

	CompoundCommand fDeleteLinksCmd;
	CompoundCommand fDeletePLTsCmd;

	public DeleteChildCommand(EObject child) {
		super(new ArrayList(2));

		fParent = child.eContainer();

		if (fParent instanceof FaultHandler || fParent instanceof EventHandler) {
			// If the child of the FH/EH is the *only* child, then we want to
			// delete the
			// entire FH/EH, since it has no meaningful attributes of its own.
			IContainer<EObject> container = BPELUtil.adapt(fParent,
					IContainer.class);
			List<EObject> children = container.getChildren(fParent);
			if (children.size() == 1 && children.contains(child)) {
				// delete the FH instead
				child = fParent;
				fParent = child.eContainer();
			}
		}
		this.fChild = child;

		if (fParent != null) {
			addModelRoot(fParent);
		}

		fContainer = BPELUtil.adapt(fParent, IContainer.class);

		String childType = null;

		ILabeledElement labeledElement = BPELUtil.adapt(child,
				ILabeledElement.class);
		if (labeledElement != null) {
			childType = labeledElement.getTypeLabel(child);
		}
		if (childType == null) {
			childType = Messages.DeleteChildCommand_Item_1;
		}
		setLabel(NLS.bind(Messages.DeleteChildCommand_Delete_2,
				(new Object[] { childType })));
	}

	/**
	 * @see org.eclipse.bpel.ui.commands.util.AutoUndoCommand#canDoExecute()
	 */
	@Override
	public boolean canDoExecute() {
		if (fChild == null || fParent == null || fContainer == null) {
			return false;
		}
		return fContainer.canRemoveChild(fParent, fChild);
	}

	// TODO: this is a hack.
	@Override
	public Resource[] getResources() {
		if (resourcesToModify == null) {
			Process process = BPELUtils.getProcess(fParent);
			if (process == null)
				return EMPTY_RESOURCE_ARRAY;
			BPELEditor bpelEditor = ModelHelper.getBPELEditor(process);

			Set<Resource> resultSet = new HashSet<Resource>();
			resultSet.add(fParent.eResource());

			// Figure out which model objects are being deleted.
			HashSet<Object> deletingSet = new HashSet<Object>();
			ModelHelper.addSubtreeToCollection(fChild, deletingSet);

			// If we are deleting any PartnerLinks which reference PLTs in the
			// Artifacts WSDL
			// file, also delete the referenced PLTs.
			Set<PartnerLinkType> partnerLinkTypes = null;
			Definition artifactsDefinition = bpelEditor
					.getArtifactsDefinition();

			for (Iterator it = deletingSet.iterator(); it.hasNext();) {
				Object object = it.next();
				if (object instanceof PartnerLink) {
					PartnerLinkType plt = ((PartnerLink) object)
							.getPartnerLinkType();
					if ((plt != null)
							&& (plt.getEnclosingDefinition() == artifactsDefinition)) {
						if (partnerLinkTypes == null)
							partnerLinkTypes = new HashSet<PartnerLinkType>();
						if (partnerLinkTypes.add(plt)) {
							resultSet.add(plt.eResource());
						}
					}
				}
			}
			resourcesToModify = resultSet
					.toArray(new Resource[resultSet.size()]);
		}
		return resourcesToModify;
	}

	/**
	 * @see org.eclipse.bpel.ui.commands.util.AutoUndoCommand#doExecute()
	 */
	@Override
	public void doExecute() {

		if (!canExecute()) {
			throw new IllegalStateException();
		}

		Process process = BPELUtils.getProcess(fParent);
		if (process == null)
			return;
		BPELEditor bpelEditor = ModelHelper.getBPELEditor(process);

		EObject topModelObject = process;

		// Multi-delete safety: if the child does not have a resource, assume it
		// has
		// already been deleted, and do nothing.
		if (fChild.eResource() == null) {
			return;
		}

		// Figure out which model objects are being deleted.
		HashSet deletingSet = new HashSet();
		ModelHelper.addSubtreeToCollection(fChild, deletingSet);

		// If we are deleting any PartnerLinks which reference PLTs in the
		// Artifacts WSDL
		// file, also delete the referenced PLTs.
		Set<PartnerLinkType> partnerLinkTypes = null;
		Definition artifactsDefinition = bpelEditor.getArtifactsDefinition();

		for (Iterator it = deletingSet.iterator(); it.hasNext();) {
			Object object = it.next();
			if (object instanceof PartnerLink) {
				PartnerLinkType plt = ((PartnerLink) object)
						.getPartnerLinkType();
				if ((plt != null)
						&& (plt.getEnclosingDefinition() == artifactsDefinition)) {
					// We should ask the user if delete the partner link type
					if (MessageDialog
							.openQuestion(
									PlatformUI.getWorkbench()
											.getActiveWorkbenchWindow()
											.getShell(),
									Messages.DeletePartnerLinkTypeWarningDialogTitle,
									NLS.bind(Messages.DeletePartnerLinkTypeWarningMessage,
											 (new Object[] {((PartnerLink) object).getName(), plt.getName() })))) {
						if (partnerLinkTypes == null)
							partnerLinkTypes = new HashSet<PartnerLinkType>();
						if (partnerLinkTypes.add(plt)) {
							if (fDeletePLTsCmd == null)
								fDeletePLTsCmd = new CompoundCommand();
							fDeletePLTsCmd
									.add(new DeletePartnerLinkTypeCommand(plt));
						}
					}
				}
			}
		}

		// TODO: Build the set of "all model objects" and subtract...
		HashSet notDeletingSet = new HashSet();
		ModelHelper.addSubtreeToCollection(topModelObject, notDeletingSet);
		notDeletingSet.removeAll(deletingSet);

		// We also need to find any flow links which involve a deleted object
		// and remove them.
		// This is a hack, but it could be worse..

		// step 1: find all the flows which contain deleted objects
		HashSet<Flow> flowSet = new HashSet<Flow>();
		for (Iterator<EObject> it = deletingSet.iterator(); it.hasNext();) {
			Flow[] flws = FlowLinkUtil.getParentFlows(it.next());
			flowSet.addAll(Arrays.asList(flws));
		}
		// step 2: if any of the flows is being deleted, we can ignore it
		// this is safe because the source, dest and link itself are all
		// children of the flow
		flowSet.removeAll(deletingSet);

		// step 3: check each link in each of the remaining flows to see if it
		// involves a
		// deleted object. Even if both source and target are being deleted, we
		// should still
		// delete the link, since it is a child of the Flow which is not being
		// deleted.
		fDeleteLinksCmd = new CompoundCommand();
		for (Iterator<Flow> flowIt = flowSet.iterator(); flowIt.hasNext();) {
			Flow flow = flowIt.next();
			for (Iterator<Link> it = FlowLinkUtil.getFlowLinks(flow).iterator(); it
					.hasNext();) {
				Link link = it.next();
				if (deletingSet.contains(FlowLinkUtil.getLinkSource(link))
						|| deletingSet.contains(FlowLinkUtil
								.getLinkTarget(link))) {
					// NOTE: this is safe even if the link is scheduled for
					// deletion by
					// a GEF DeleteAction, see comment in DeleteLinkCommand.
					DeleteLinkCommand child = new DeleteLinkCommand(link);
					if (child.canExecute())
						fDeleteLinksCmd.add(child);
				}
			}
		}

		fDeleteLinksCmd.doExecute();

		if (fDeletePLTsCmd != null) {
			fDeletePLTsCmd.doExecute();
		}

		// finally, we can remove the child.
		fContainer.removeChild(fParent, fChild);

		// IMPORTANT: since the parent is a not-deleted object and the child
		// will be
		// a deleted object, this step must be done *after* the IContainer
		// removal ;)
		for (Iterator it = notDeletingSet.iterator(); it.hasNext();) {
			BPELUtil.deleteNonContainmentRefs((EObject) it.next(), deletingSet);
		}
	}
}
