/*******************************************************************************
 * 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.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.bpel.model.Activity;
import org.eclipse.bpel.model.Flow;
import org.eclipse.bpel.model.Link;
import org.eclipse.bpel.model.Source;
import org.eclipse.bpel.model.Sources;
import org.eclipse.bpel.model.Target;
import org.eclipse.bpel.model.Targets;
import org.eclipse.bpel.model.util.BPELUtils;
import org.eclipse.bpel.ui.commands.util.AutoUndoCommand;
import org.eclipse.bpel.ui.util.FlowLinkUtil;
import org.eclipse.bpel.ui.util.ModelHelper;



/**
 * Revalidate all the links for which the given activity(s) are the source or target.
 * 
 * For each link, the link should be contained in the innermost enclosing Flow which
 * contains both the source and the target.  If there is no such flow, the link is
 * deleted.  If there is such a flow and the Link is not currently owned by it, the
 * Link is moved into that Flow (and renamed, if necessary, to prevent naming collisions). 
 */
public class RevalidateLinksCommand extends AutoUndoCommand {

	List<Activity> activities;
	CompoundCommand deleteLinksCmd;
	
	public RevalidateLinksCommand(Collection activityCollection) {
		super(new ArrayList(1));
		this.activities = new ArrayList(activityCollection.size());
		this.activities.addAll(activityCollection);
		if (!activityCollection.isEmpty()) {
			addModelRoot(BPELUtils.getProcess(activityCollection.iterator().next()));
		}
	}
	
	// TODO: can we use the unique name support instead?
	protected boolean isAcceptableLinkName(Flow flow, String proposedName) {
		for (Iterator it = FlowLinkUtil.getFlowLinks(flow).iterator(); it.hasNext(); ) {
			Link link = (Link)it.next();
			if (proposedName.equals(link.getName())) return false;
		}
		return true;
	}
	
	protected void revalidateLink(Link link) {
		Flow linkFlow = (Flow)(link.eContainer().eContainer());
		Activity source = FlowLinkUtil.getLinkSource(link);
		Activity target = FlowLinkUtil.getLinkTarget(link);
		Flow commonFlow = FlowLinkUtil.getCommonFlow(source, target);
		if (commonFlow == null) {
			// We must delete this link.  Queue it up for deletion (don't delete
			// right away, as that would disturb the list(s) of sources/targets
			// which we are iterating over).
			deleteLinksCmd.add(new DeleteLinkCommand(link));
		} else if (commonFlow != linkFlow) {
			// Move this link into the commonFlow.
			// First, make sure none of the links in the commonFlow has the same name!
			if (!isAcceptableLinkName(commonFlow, link.getName())) {
				String s;
				int i = 0;
				do {
					++i; s = link.getName()+"_"+i; //$NON-NLS-1$
				} while (!isAcceptableLinkName(commonFlow, s));
				link.setName(s);
			}
			FlowLinkUtil.removeFlowLink(linkFlow, link);
			FlowLinkUtil.addFlowLink(commonFlow, link);
		}
	}
	
	@Override
	public void doExecute() {
		deleteLinksCmd = new CompoundCommand();
		
		// Figure out which model objects are being moved.
		HashSet revalidatingSet = new HashSet();
		for (Iterator<Activity> it = activities.iterator(); it.hasNext(); ) {
			Activity activity = it.next();
			ModelHelper.addSubtreeToCollection(activity, revalidatingSet);
		}
		for (Iterator it = revalidatingSet.iterator(); it.hasNext(); ) {
			Object object = it.next();
			if (object instanceof Activity) { 
				Activity activity = (Activity)object;
				Sources sources = activity.getSources();
				if (sources != null) {
					Iterator<Source> it2 = sources.getChildren().iterator();
					while (it2.hasNext()) revalidateLink((it2.next()).getLink());
				}
				Targets targets = activity.getTargets();
				if (targets != null) {
					Iterator<Target> it2 = targets.getChildren().iterator();
					while (it2.hasNext()) revalidateLink((it2.next()).getLink());
				}
			}
		}
		// delete any links that we queued up for deletion.
		if (!deleteLinksCmd.isEmpty()) deleteLinksCmd.execute();
	}
}
