/**
 * <copyright>
 * 
 * Copyright (c) 2014 Thales Corporate Services S.A.S.
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-v2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 * Thales Corporate Services S.A.S - initial API and implementation
 * 
 * </copyright>
 */
package org.eclipse.egf.portfolio.genchain.ecoretools.command;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.sirius.business.api.session.Session;
import org.eclipse.sirius.common.tools.api.interpreter.EvaluationException;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.diagram.DDiagram;
import org.eclipse.sirius.diagram.DDiagramElementContainer;
import org.eclipse.sirius.diagram.DNode;
import org.eclipse.sirius.diagram.DSemanticDiagram;
import org.eclipse.sirius.diagram.EdgeTarget;
import org.eclipse.sirius.diagram.business.api.componentization.DiagramMappingsManager;
import org.eclipse.sirius.diagram.business.api.query.EdgeMappingQuery;
import org.eclipse.sirius.diagram.business.internal.componentization.mappings.DiagramMappingsManagerRegistryImpl;
import org.eclipse.sirius.diagram.business.internal.experimental.sync.DDiagramElementSynchronizer;
import org.eclipse.sirius.diagram.business.internal.experimental.sync.DDiagramSynchronizer;
import org.eclipse.sirius.diagram.business.internal.experimental.sync.DEdgeCandidate;
import org.eclipse.sirius.diagram.description.ContainerMapping;
import org.eclipse.sirius.diagram.description.DiagramElementMapping;
import org.eclipse.sirius.diagram.description.EdgeMapping;
import org.eclipse.sirius.diagram.description.MappingBasedDecoration;
import org.eclipse.sirius.diagram.description.NodeMapping;
import org.eclipse.sirius.viewpoint.DSemanticDecorator;
import org.eclipse.sirius.viewpoint.description.SemanticBasedDecoration;

//import org.eclipse.sirius.business.internal.componentization.mappings.DiagramMappingsManagerRegistryImpl;
//import org.eclipse.sirius.business.internal.experimental.sync.DDiagramElementSynchronizer;
//import org.eclipse.sirius.business.internal.experimental.sync.DDiagramSynchronizer;
//import org.eclipse.sirius.business.internal.experimental.sync.DEdgeCandidate;
//import org.eclipse.sirius.business.api.componentization.DiagramMappingsManager;
//import org.eclipse.sirius.business.api.query.EdgeMappingQuery;

/**
 * Recording command allowing to create an Edge in a diagram.
 * 
 * @see CreateNodeCommand
 * 
 * @author Boubekeur Zendagui
 */
@SuppressWarnings("restriction")
public class CreateEdgeCommand extends RecordingCommand {

	/** Command properties **/
	private DDiagram _diagram;
	private Session _session;
	private EdgeMapping _mapping;
	private EObject _target;
	private boolean _isElementBasedEdge;
	
	/**
	 * Default constructor
	 * @param session the {@link Session} used to create the Edge
	 * @param diagramthe {@link DDiagram} wherein the Edge will be created
	 * @param mapping the {@link EdgeMapping} describing the edge
	 * @param target {@link EObject} used as target semantic element of the edge
	 * @param isElementBasedEdge if <code> true </code> the edge is an element based edge
	 */
	public CreateEdgeCommand(Session session, DDiagram diagram, EdgeMapping mapping, EObject target, boolean isElementBasedEdge){
		this(session.getTransactionalEditingDomain());
		this._diagram = diagram;
		this._session = session;
		this._mapping = mapping;
		this._target = target;
		this._isElementBasedEdge = isElementBasedEdge;
	}
	
	/**
	 * Hidden constructor
	 * @param domain a {@link TransactionalEditingDomain}
	 */
	private CreateEdgeCommand(TransactionalEditingDomain domain) {
		super(domain);
	}
	
	@Override
	protected void doExecute() {
		final DDiagramSynchronizer diagramSynchronizer = new DDiagramSynchronizer(_session.getInterpreter(), _diagram.getDescription(), _session.getModelAccessor());
		diagramSynchronizer.setDiagram((DSemanticDiagram)_diagram);
		
		/* maps for decorations */
		Map<EdgeMapping, Collection<MappingBasedDecoration>> edgeToMappingBasedDecoration = new HashMap<EdgeMapping, Collection<MappingBasedDecoration>>();
		Map<String, Collection<SemanticBasedDecoration>> edgeToSemanticBasedDecoration = new HashMap<String, Collection<SemanticBasedDecoration>>();

		/* create the mapping to edge targets map */
		DDiagramElementSynchronizer elementSynchronizer = diagramSynchronizer.getElementSynchronizer();
		Map<DiagramElementMapping, Collection<EdgeTarget>> mappingsToEdgeTargets = elementSynchronizer.computeMappingsToEdgeTargets(_session.getSelectedViewpoints(false));
		diagramSynchronizer.computeDecorations(mappingsToEdgeTargets, edgeToSemanticBasedDecoration, edgeToMappingBasedDecoration);
		
		final DiagramMappingsManager diagramMappingsManager = DiagramMappingsManagerRegistryImpl.INSTANCE.getDiagramMappingsManager(_session, _diagram);

		/* create Edge Candidate object*/
		try {
			/* Get all possible source nodes from the diagram */
			List<EdgeTarget> sourceNodes = getSourceNodes();
			/* Get all possible target nodes from the diagram */
			List<EdgeTarget> targetNodes = getTargetNodes();
			/* Try to create edges between sources and targets */
			for (EdgeTarget sourceEdgeTarget : sourceNodes) 
			{
				for (EdgeTarget targetEdgeTarget : targetNodes) 
				{
					// 
					EdgeMappingQuery edgeMappingQuery = new EdgeMappingQuery(_mapping);
					boolean precondition = edgeMappingQuery.evaluatePrecondition((DSemanticDiagram)_diagram, _diagram, _session.getInterpreter(), _target, (DSemanticDecorator)sourceEdgeTarget, (DSemanticDecorator)targetEdgeTarget);
					if (precondition)
					{
						DEdgeCandidate candidate = new DEdgeCandidate(_mapping,_target, sourceEdgeTarget, targetEdgeTarget);
						elementSynchronizer.createNewEdge(diagramMappingsManager, candidate, mappingsToEdgeTargets, edgeToMappingBasedDecoration, edgeToSemanticBasedDecoration);
					}
				}
			}
		} catch (EvaluationException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Get all source
	 * @return a list of {@link EdgeTarget} element candidate to be source node
	 * @throws EvaluationException
	 */
	public List<EdgeTarget> getSourceNodes() throws EvaluationException{
		List<EdgeTarget> result = new ArrayList<EdgeTarget>();
		Collection<EObject> sematicSources = new ArrayList<EObject>();
		
		IInterpreter interpreter = _session.getInterpreter();
		if (_isElementBasedEdge)
			sematicSources = interpreter.evaluateCollection(_target, _mapping.getSourceFinderExpression());
		else
			sematicSources.add(_target);

		EList<DiagramElementMapping> sourceMapping = _mapping.getSourceMapping();
		for (EObject eObject : sematicSources) 
		{
			List<EdgeTarget> sources = getNodesFromDiagram(sourceMapping, eObject);
			if (! sources.isEmpty())
				result.addAll(sources);
		}

		return result;
	}
	
	public List<EdgeTarget> getTargetNodes() throws EvaluationException{
		List<EdgeTarget> result = new ArrayList<EdgeTarget>();
		IInterpreter interpreter = _session.getInterpreter();
		Collection<EObject> sematicTarget = new ArrayList<EObject>();
		try {
			sematicTarget = interpreter.evaluateCollection(_target, _mapping.getTargetFinderExpression());
		} catch (EvaluationException e) {
			// TODO: handle exception
		}

		EList<DiagramElementMapping> targetMapping = _mapping.getTargetMapping();
		for (EObject eObject : sematicTarget) 
		{
			List<EdgeTarget> targets = getNodesFromDiagram(targetMapping, eObject);
			if (! targets.isEmpty())
				result.addAll(targets);
		}

		return result;
	}

	/**
	 * Get node from diagram
	 * @param mapping a list of {@link DiagramElementMapping} 
	 * @param semantic the semantic element
	 * @return
	 */
	private List<EdgeTarget> getNodesFromDiagram(EList<DiagramElementMapping> mapping, EObject semantic) {
		List<EdgeTarget> result = new ArrayList<EdgeTarget>();
		// Get the diagram node for which semantic element is target
		for (DiagramElementMapping diagramElementMapping : mapping) 
		{
			if (diagramElementMapping instanceof ContainerMapping)
			{
				EList<DDiagramElementContainer> containers = _diagram.getContainersFromMapping((ContainerMapping) diagramElementMapping);
				for (DDiagramElementContainer dDiagramElementContainer : containers) 
				{
					if (dDiagramElementContainer.getTarget().equals(semantic))
						result.add(dDiagramElementContainer);
				}
				
			}
			
			if (diagramElementMapping instanceof NodeMapping)
			{
				EList<DNode> nodes = _diagram.getNodesFromMapping((NodeMapping) diagramElementMapping);
				for (DNode dNode : nodes) 
				{
					if (dNode.getTarget().equals(semantic))
						result.add(dNode);
				}
			}
		}
		return result;
	}

}
