/*******************************************************************************
 * Copyright (c) 2007, 2016 THALES GLOBAL SERVICES 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:
 *    Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.sirius.diagram.business.internal.experimental.sync;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.sirius.business.api.logger.RuntimeLoggerManager;
import org.eclipse.sirius.common.tools.DslCommonPlugin;
import org.eclipse.sirius.common.tools.api.interpreter.EvaluationException;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterSiriusVariables;
import org.eclipse.sirius.common.tools.api.util.StringUtil;
import org.eclipse.sirius.diagram.AbstractDNode;
import org.eclipse.sirius.diagram.DDiagram;
import org.eclipse.sirius.diagram.DDiagramElement;
import org.eclipse.sirius.diagram.DDiagramElementContainer;
import org.eclipse.sirius.diagram.DEdge;
import org.eclipse.sirius.diagram.DNode;
import org.eclipse.sirius.diagram.DNodeContainer;
import org.eclipse.sirius.diagram.DNodeList;
import org.eclipse.sirius.diagram.DNodeListElement;
import org.eclipse.sirius.diagram.DSemanticDiagram;
import org.eclipse.sirius.diagram.DiagramFactory;
import org.eclipse.sirius.diagram.DiagramPackage;
import org.eclipse.sirius.diagram.DragAndDropTarget;
import org.eclipse.sirius.diagram.EdgeStyle;
import org.eclipse.sirius.diagram.EdgeTarget;
import org.eclipse.sirius.diagram.NodeStyle;
import org.eclipse.sirius.diagram.WorkspaceImage;
import org.eclipse.sirius.diagram.business.api.componentization.DiagramDescriptionMappingsManager;
import org.eclipse.sirius.diagram.business.api.componentization.DiagramMappingsManager;
import org.eclipse.sirius.diagram.business.api.helper.SiriusDiagramHelper;
import org.eclipse.sirius.diagram.business.api.helper.display.DisplayMode;
import org.eclipse.sirius.diagram.business.api.helper.display.DisplayService;
import org.eclipse.sirius.diagram.business.api.helper.display.DisplayServiceManager;
import org.eclipse.sirius.diagram.business.api.helper.graphicalfilters.HideFilterHelper;
import org.eclipse.sirius.diagram.business.api.query.ContainerMappingQuery;
import org.eclipse.sirius.diagram.business.api.query.DiagramDescriptionMappingManagerQuery;
import org.eclipse.sirius.diagram.business.api.query.IEdgeMappingQuery;
import org.eclipse.sirius.diagram.business.internal.componentization.mappings.DiagramDescriptionMappingsManagerImpl;
import org.eclipse.sirius.diagram.business.internal.metamodel.helper.DiagramElementMappingHelper;
import org.eclipse.sirius.diagram.business.internal.metamodel.helper.LayerHelper;
import org.eclipse.sirius.diagram.business.internal.metamodel.helper.MappingHelper;
import org.eclipse.sirius.diagram.business.internal.metamodel.helper.StyleHelper;
import org.eclipse.sirius.diagram.description.AbstractNodeMapping;
import org.eclipse.sirius.diagram.description.ContainerMapping;
import org.eclipse.sirius.diagram.description.DescriptionPackage;
import org.eclipse.sirius.diagram.description.DiagramDescription;
import org.eclipse.sirius.diagram.description.DiagramElementMapping;
import org.eclipse.sirius.diagram.description.EdgeMapping;
import org.eclipse.sirius.diagram.description.IEdgeMapping;
import org.eclipse.sirius.diagram.description.MappingBasedDecoration;
import org.eclipse.sirius.diagram.description.NodeMapping;
import org.eclipse.sirius.diagram.description.style.ContainerStyleDescription;
import org.eclipse.sirius.diagram.description.style.EdgeStyleDescription;
import org.eclipse.sirius.diagram.description.style.EllipseNodeDescription;
import org.eclipse.sirius.diagram.description.style.LozengeNodeDescription;
import org.eclipse.sirius.diagram.description.style.NodeStyleDescription;
import org.eclipse.sirius.diagram.description.style.SquareDescription;
import org.eclipse.sirius.diagram.description.style.WorkspaceImageDescription;
import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
import org.eclipse.sirius.ext.base.Option;
import org.eclipse.sirius.ext.base.Options;
import org.eclipse.sirius.tools.api.interpreter.IInterpreterMessages;
import org.eclipse.sirius.tools.api.profiler.SiriusTasksKey;
import org.eclipse.sirius.viewpoint.DSemanticDecorator;
import org.eclipse.sirius.viewpoint.Decoration;
import org.eclipse.sirius.viewpoint.Style;
import org.eclipse.sirius.viewpoint.ViewpointFactory;
import org.eclipse.sirius.viewpoint.description.DecorationDescription;
import org.eclipse.sirius.viewpoint.description.SemanticBasedDecoration;
import org.eclipse.sirius.viewpoint.description.Viewpoint;
import org.eclipse.sirius.viewpoint.description.style.BasicLabelStyleDescription;
import org.eclipse.sirius.viewpoint.description.style.LabelStyleDescription;
import org.eclipse.sirius.viewpoint.description.style.StyleDescription;
import org.eclipse.sirius.viewpoint.description.style.StylePackage;
import org.eclipse.sirius.viewpoint.description.style.TooltipStyleDescription;

import com.google.common.base.Objects;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;

/**
 * This class is able to synchronize diagram elements and styles.
 * 
 * @author cbrun
 */
public class DDiagramElementSynchronizer {

    private final IInterpreter interpreter;

    private final DSemanticDiagram diagram;

    private final ModelAccessor accessor;

    private final StyleHelper styleHelper;

    private final MappingHelper mappingHelper;

    /**
     * Create a new synchronizer for the given diagram.
     * 
     * @param diagram
     *            diagram to synchronize.
     * @param interpreter
     *            current interpreter.
     * @param accessor
     *            model accessor
     */
    public DDiagramElementSynchronizer(final DSemanticDiagram diagram, final IInterpreter interpreter, final ModelAccessor accessor) {
        super();
        this.diagram = diagram;
        this.interpreter = interpreter;
        this.accessor = accessor;
        this.styleHelper = new StyleHelper(interpreter);
        this.mappingHelper = new MappingHelper(interpreter);
    }

    /**
     * Create completely a new Node with its style and so on from a candidate.
     * 
     * @param mappingManager
     *            the manager used to handle return the Mappings to consider
     *            regarding the enablement of Viewpoints.
     * @param candidate
     *            the node candidate, it contains the mapping and the semantic
     *            target.
     * @param isBorder
     *            true if the element is a border one.
     * @return newly created node.
     */
    public AbstractDNode createNewNode(DiagramMappingsManager mappingManager, final AbstractDNodeCandidate candidate, final boolean isBorder) {
        return createNewNode(mappingManager, candidate, isBorder, -1);
    }

    /**
     * Build a new Node from a candidate.
     * 
     * @param mappingManager
     *            the manager used to handle return the Mappings to consider
     *            regarding the enablement of Viewpoints.
     * @param candidate
     *            the node candidate, it contains the mapping and the semantic
     *            target.
     * @param isBorder
     *            true if the element is a border one.
     * @param insertionIndex
     *            the insertion index. give a negative value if you don't care
     * @return newly created node.
     */
    public AbstractDNode createNewNode(DiagramMappingsManager mappingManager, final AbstractDNodeCandidate candidate, final boolean isBorder, final int insertionIndex) {
        final DragAndDropTarget container = candidate.getViewContainer();
        final AbstractDNode newNode = createAbstractNode(container, candidate, isBorder);
        if (insertionIndex > 0) {
            SiriusDiagramHelper.addNodeInContainer(container, isBorder, newNode, insertionIndex);
        } else {
            SiriusDiagramHelper.addNodeInContainer(container, isBorder, newNode);
        }
        refresh(newNode);
        refreshSemanticElements(newNode, candidate.getMapping());
        createStyle(newNode, candidate.getMapping());
        computeVisibilityOnCreation(mappingManager, newNode);
        return newNode;
    }

    /**
     * Build a new Node from a candidate.
     * 
     * @param container
     *            the object who will contain the new node.
     * @param candidate
     *            the node candidate, it contains the mapping and the semantic
     *            target.
     * @param border
     *            true if the element is a border one.
     * @return newly created node.
     */
    private AbstractDNode createAbstractNode(final DragAndDropTarget container, final AbstractDNodeCandidate candidate, final boolean border) {
        AbstractDNode result = null;
        if (candidate.getMapping() instanceof NodeMapping) {
            final NodeMapping mapping = (NodeMapping) candidate.getMapping();
            if (container instanceof DNodeList) {
                if (!border) {
                    final DNodeListElement newNode = DiagramFactory.eINSTANCE.createDNodeListElement();
                    newNode.setTarget(candidate.getSemantic());
                    newNode.setActualMapping(mapping);
                    result = newNode;
                } else {
                    final DNode newNode = DiagramFactory.eINSTANCE.createDNode();
                    newNode.setTarget(candidate.getSemantic());
                    newNode.setActualMapping(mapping);
                    result = newNode;
                }
            } else {
                final DNode newNode = DiagramFactory.eINSTANCE.createDNode();
                newNode.setTarget(candidate.getSemantic());
                newNode.setActualMapping(mapping);
                result = newNode;

            }

        } else if (candidate.getMapping() instanceof ContainerMapping) {
            final ContainerMapping mapping = (ContainerMapping) candidate.getMapping();
            DDiagramElementContainer newContainer = null;
            if (new ContainerMappingQuery(mapping).isListContainer()) {
                newContainer = DiagramFactory.eINSTANCE.createDNodeList();
            } else {
                // Other behaviors : ContainerLayout.FreeForm/VerticalStack
                DNodeContainer nodeContainer = DiagramFactory.eINSTANCE.createDNodeContainer();
                nodeContainer.setChildrenPresentation(mapping.getChildrenPresentation());
                newContainer = nodeContainer;
            }
            newContainer.setTarget(candidate.getSemantic());
            newContainer.setActualMapping(mapping);
            result = newContainer;
        }
        return result;
    }

    /**
     * Compute a mappings to edge target map for a given diagram.
     * 
     * @param enabledVp
     *            the list of viewpoints to consider
     * 
     * @return the requested map
     */
    public Map<DiagramElementMapping, Collection<EdgeTarget>> computeMappingsToEdgeTargets(Collection<Viewpoint> enabledVp) {
        final Map<DiagramElementMapping, Collection<EdgeTarget>> mappingsToEdgeTargets = new HashMap<DiagramElementMapping, Collection<EdgeTarget>>();

        final DiagramDescription description = diagram.getDescription();

        final DiagramDescriptionMappingsManager mappingsManager = new DiagramDescriptionMappingsManagerImpl(description);
        mappingsManager.computeMappings(enabledVp);
        final Set<DiagramElementMapping> allMappings = new DiagramDescriptionMappingManagerQuery(mappingsManager).computeAllMappings();
        final Iterable<NodeMapping> allNodeMappings = Iterables.filter(allMappings, NodeMapping.class);
        final Iterable<ContainerMapping> allContainerMappings = Iterables.filter(allMappings, ContainerMapping.class);
        final Iterable<EdgeMapping> allEdgeMappings = Iterables.filter(allMappings, EdgeMapping.class);

        for (final NodeMapping nodeMapping : allNodeMappings) {
            final List<DNode> nodes = diagram.getNodesFromMapping(nodeMapping);
            if (!nodes.isEmpty()) {
                mappingsToEdgeTargets.put(nodeMapping, DDiagramElementSynchronizer.convertNodesAndContainersToEdgeTarget(nodes));
            }
        }

        for (final ContainerMapping containerMapping : allContainerMappings) {
            final List<DDiagramElementContainer> containers = diagram.getContainersFromMapping(containerMapping);
            if (!containers.isEmpty()) {
                mappingsToEdgeTargets.put(containerMapping, DDiagramElementSynchronizer.convertNodesAndContainersToEdgeTarget(containers));
            }
        }

        for (final EdgeMapping edgeMapping : allEdgeMappings) {
            final List<DEdge> edges = diagram.getEdgesFromMapping(edgeMapping);
            if (!edges.isEmpty()) {
                mappingsToEdgeTargets.put(edgeMapping, DDiagramElementSynchronizer.convertNodesAndContainersToEdgeTarget(edges));
            }
        }

        return mappingsToEdgeTargets;
    }

    private static Collection<EdgeTarget> convertNodesAndContainersToEdgeTarget(final Collection<? extends DDiagramElement> diagramElements) {
        return ImmutableSet.copyOf(Iterables.filter(diagramElements, EdgeTarget.class));
    }

    /**
     * Create completely a new Edge with it style path and so on from a
     * candidate and the mappings maps.
     * 
     * @param mappingManager
     *            the manager used to handle return the Mappings to consider
     *            regarding the enablement of Viewpoints.
     * @param candidate
     *            the edge candidate
     * @param mappingsToEdgeTargets
     *            mappings to edge targets map
     * @param edgeToMappingBasedDecoration
     *            a map with for key a mapping and for value the associated
     *            decorations
     * @param edgeToSemanticBasedDecoration
     *            a map with for key a domain class as string and for value the
     *            associated decorations
     * @return the created edge
     */
    public DEdge createNewEdge(DiagramMappingsManager mappingManager, final DEdgeCandidate candidate, final Map<DiagramElementMapping, Collection<EdgeTarget>> mappingsToEdgeTargets,
            final Map<EdgeMapping, Collection<MappingBasedDecoration>> edgeToMappingBasedDecoration, final Map<String, Collection<SemanticBasedDecoration>> edgeToSemanticBasedDecoration) {

        DslCommonPlugin.PROFILER.startWork(SiriusTasksKey.CREATE_MISSING_EDGES_KEY);
        DEdge newEdge = createEdge(candidate);
        diagram.getOwnedDiagramElements().add(newEdge);

        Option<EdgeMapping> edgeMapping = new IEdgeMappingQuery(candidate.getMapping()).getEdgeMapping();
        if (edgeMapping.some()) {
            refreshSemanticElements(newEdge, edgeMapping.get());
            createStyle(newEdge, edgeMapping.get(), diagram);
            refresh(newEdge);
            updatePath(newEdge, edgeMapping.get(), mappingsToEdgeTargets);
        }

        computeEdgeDecorations(newEdge, edgeToMappingBasedDecoration, edgeToSemanticBasedDecoration);
        computeVisibilityOnCreation(mappingManager, newEdge);

        DslCommonPlugin.PROFILER.stopWork(SiriusTasksKey.CREATE_MISSING_EDGES_KEY);
        return newEdge;
    }

    /**
     * Create a new Edge from a candidate.
     * 
     * @param candidate
     *            the edge candidate containing the mapping and the edge
     *            semantic target (among other things).
     * @return the newly created edge.
     */
    private DEdge createEdge(final DEdgeCandidate candidate) {
        final DEdge newEdge = DiagramFactory.eINSTANCE.createDEdge();
        newEdge.setTarget(candidate.getSemantic());
        newEdge.setActualMapping(candidate.getMapping());
        newEdge.setSourceNode(candidate.getSourceView());
        newEdge.setTargetNode(candidate.getTargetView());
        return newEdge;
    }

    private void computeVisibilityOnCreation(DiagramMappingsManager mappingManager, final DDiagramElement element) {
        final DisplayService service = DisplayServiceManager.INSTANCE.getDisplayService(DisplayMode.CREATION);
        if (service == null) {
            return;
        }

        DslCommonPlugin.PROFILER.startWork(SiriusTasksKey.IS_VISIBLE_KEY);
        element.setVisible(service.computeVisibility(mappingManager, diagram, element));
        if (!service.computeLabelVisibility(diagram, element)) {
            HideFilterHelper.INSTANCE.hideLabel(element);
        }
        DslCommonPlugin.PROFILER.stopWork(SiriusTasksKey.IS_VISIBLE_KEY);
    }

    /**
     * Compute edge decorations.
     * 
     * @param edge
     *            the edge
     * @param edgeToMappingBasedDecoration
     *            a map with for key a mapping and for value the associated
     *            decorations
     * @param edgeToSemanticBasedDecoration
     *            a map with for key a domain class as string and for value the
     *            associated decorations
     */
    public void computeEdgeDecorations(final DEdge edge, final Map<EdgeMapping, Collection<MappingBasedDecoration>> edgeToMappingBasedDecoration,
            final Map<String, Collection<SemanticBasedDecoration>> edgeToSemanticBasedDecoration) {
        /* semantic based decorations */
        IEdgeMapping actualMapping = edge.getActualMapping();
        final Option<EdgeMapping> edgeMapping = new IEdgeMappingQuery(actualMapping).getEdgeMapping();
        if (edgeMapping.some() && edgeMapping.get().isUseDomainElement() && edgeToSemanticBasedDecoration.containsKey(edgeMapping.get().getDomainClass())) {
            final Collection<SemanticBasedDecoration> semanticBasedDecorations = edgeToSemanticBasedDecoration.get(edgeMapping.get().getDomainClass());
            for (final SemanticBasedDecoration semanticBasedDecoration : semanticBasedDecorations) {
                this.addDecoration(edge, semanticBasedDecoration);
            }
        }
        /* mapping based decoration */
        if (edgeToMappingBasedDecoration.containsKey(actualMapping)) {
            final Collection<MappingBasedDecoration> mappingBasedDecorations = edgeToMappingBasedDecoration.get(actualMapping);
            for (final MappingBasedDecoration mappingBasedDecoration : mappingBasedDecorations) {
                this.addDecoration(edge, mappingBasedDecoration);
            }
        }
    }

    /**
     * Refresh an edge computing it's new size and style.
     * 
     * @param edge
     *            edge to be refreshed.
     */
    protected void refresh(final DEdge edge) {
        EObject containerVariable = null;
        if (edge.eContainer() instanceof DSemanticDecorator) {
            containerVariable = ((DSemanticDecorator) edge.eContainer()).getTarget();
        }
        // Recompute the conditional style
        this.interpreter.setVariable(IInterpreterSiriusVariables.DIAGRAM, this.diagram);
        this.interpreter.setVariable(IInterpreterSiriusVariables.VIEW, edge);
        this.interpreter.setVariable(IInterpreterSiriusVariables.SOURCE_VIEW, edge.getSourceNode());
        this.interpreter.setVariable(IInterpreterSiriusVariables.TARGET_VIEW, edge.getTargetNode());

        this.mappingHelper.affectAndRefreshStyle(edge.getDiagramElementMapping(), edge, edge.getTarget(), containerVariable, (DDiagram) edge.eContainer());

        this.interpreter.unSetVariable(IInterpreterSiriusVariables.DIAGRAM);
        this.interpreter.unSetVariable(IInterpreterSiriusVariables.VIEW);
        this.interpreter.unSetVariable(IInterpreterSiriusVariables.SOURCE_VIEW);
        this.interpreter.unSetVariable(IInterpreterSiriusVariables.TARGET_VIEW);

        final EdgeStyle edgeStyle = edge.getOwnedStyle();
        if (edgeStyle != null) {
            final EdgeStyleDescription edgeStyleDescription = (EdgeStyleDescription) edgeStyle.getDescription();
            // LABEL
            refreshCenterLabel(edge, edgeStyleDescription);
            refreshBeginLabel(edge, edgeStyleDescription);
            refreshEndLabel(edge, edgeStyleDescription);
        }

        // semantic elements
        final Option<EdgeMapping> actualMapping = new IEdgeMappingQuery(edge.getActualMapping()).getEdgeMapping();
        if (actualMapping.some()) {
            refreshSemanticElements(edge, actualMapping.get());
        }

        // clean decorations
        cleanDecoration(edge);
    }

    /**
     * @param edge
     * @param edgeStyleDescription
     */
    private void refreshEndLabel(final DEdge edge, final EdgeStyleDescription edgeStyleDescription) {
        if (edgeStyleDescription.getEndLabelStyleDescription() != null && !StringUtil.isEmpty(edgeStyleDescription.getEndLabelStyleDescription().getLabelExpression())) {
            final String label = computeLabel(edge, edgeStyleDescription.getEndLabelStyleDescription());
            edge.setEndLabel(label);
            if (!("".equals(edge.getEndLabel()) && label == null) && !StringUtil.equals(edge.getEndLabel(), label)) { //$NON-NLS-1$
                // This is a workaround for a CDO issue in legacy mode
                // (https://bugs.eclipse.org/bugs/show_bug.cgi?id=404152)
                edge.setEndLabel(label);
            }
        } else if (!StringUtil.isEmpty(edge.getEndLabel())) {
            edge.setEndLabel(""); //$NON-NLS-1$
        }
    }

    /**
     * @param edge
     * @param edgeStyleDescription
     */
    private void refreshBeginLabel(final DEdge edge, final EdgeStyleDescription edgeStyleDescription) {
        if (edgeStyleDescription.getBeginLabelStyleDescription() != null && !StringUtil.isEmpty(edgeStyleDescription.getBeginLabelStyleDescription().getLabelExpression())) {
            final String label = computeLabel(edge, edgeStyleDescription.getBeginLabelStyleDescription());
            if (!("".equals(edge.getBeginLabel()) && label == null) && !StringUtil.equals(edge.getBeginLabel(), label)) { //$NON-NLS-1$
                // This is a workaround for a CDO issue in legacy mode
                // (https://bugs.eclipse.org/bugs/show_bug.cgi?id=404152)
                edge.setBeginLabel(label);
            }
        } else if (!StringUtil.isEmpty(edge.getBeginLabel())) {
            edge.setBeginLabel(""); //$NON-NLS-1$
        }
    }

    /**
     * @param edge
     * @param edgeStyleDescription
     */
    private void refreshCenterLabel(final DEdge edge, final EdgeStyleDescription edgeStyleDescription) {
        if (edgeStyleDescription.getCenterLabelStyleDescription() != null && !StringUtil.isEmpty(edgeStyleDescription.getCenterLabelStyleDescription().getLabelExpression())) {
            final String label = computeLabel(edge, edgeStyleDescription.getCenterLabelStyleDescription());
            if (!("".equals(edge.getName()) && label == null) && !StringUtil.equals(edge.getName(), label)) { //$NON-NLS-1$
                // This is a workaround for a CDO issue in legacy mode
                // (https://bugs.eclipse.org/bugs/show_bug.cgi?id=404152)
                edge.setName(label);
            }
        } else if (!StringUtil.isEmpty(edge.getName())) {
            edge.setName(""); //$NON-NLS-1$
        }
    }

    /**
     * Refresh a DDiagramElement computing it's label, size and style.
     * 
     * @param dde
     *            node to be refreshed.
     */
    public void refresh(final DDiagramElement dde) {
        if (accessor.getPermissionAuthority().canEditInstance(dde)) {
            if (dde instanceof DNode) {
                refresh((DNode) dde);
            } else if (dde instanceof DNodeListElement) {
                refresh((DNodeListElement) dde);
            } else if (dde instanceof DDiagramElementContainer) {
                refresh((DDiagramElementContainer) dde);
            } else if (dde instanceof DEdge) {
                refresh((DEdge) dde);
            }
        }
    }

    /**
     * Refresh a list element.
     * 
     * @param newNode
     *            list element to be refreshed.
     */
    protected void refresh(final DNodeListElement newNode) {
        final DSemanticDecorator container = (DSemanticDecorator) newNode.eContainer();
        if (container != null) {
            final NodeStyleDescription style = (NodeStyleDescription) this.mappingHelper.getBestStyleDescription(newNode.getActualMapping(), newNode.getTarget(), newNode, container.getTarget(),
                    diagram);
            if (style != null) {
                refreshLabel(newNode, style);
                refreshTooltip(newNode, style);
            }
        }
        if (newNode.getOwnedStyle() != null) {
            Option<NodeStyle> noPreviousStyle = Options.newNone();
            styleHelper.refreshStyle(newNode.getOwnedStyle(), noPreviousStyle);
        }
        refreshSemanticElements(newNode, newNode.getDiagramElementMapping());
    }

    /**
     * Refresh a container.
     * 
     * @param container
     *            element to be refreshed.
     */
    protected void refresh(final DDiagramElementContainer container) {
        final DSemanticDecorator cContainer = (DSemanticDecorator) container.eContainer();
        ContainerMapping containerMapping = container.getActualMapping();
        if (cContainer != null) {
            ContainerStyleDescription containerStyleDescription = null;
            if (hasSafeTarget(container) && hasSafeTarget(cContainer)) {
                containerStyleDescription = (ContainerStyleDescription) this.mappingHelper.getBestStyleDescription(containerMapping, container.getTarget(), container, cContainer.getTarget(), diagram);
            }
            if (containerStyleDescription != null) {
                refreshLabel(container, containerStyleDescription);
                refreshTooltip(container, containerStyleDescription);
                refreshStyle(container, containerMapping);
            }
        }
        // clean decorations
        cleanDecoration(container);
        refreshSemanticElements(container, containerMapping);
    }

    private void cleanDecoration(final DDiagramElement element) {
        Iterator<Decoration> it = element.getDecorations().iterator();
        while (it.hasNext()) {
            Decoration decoration = it.next();
            final DecorationDescription description = decoration.getDescription();
            if (!diagram.getActivatedLayers().contains(LayerHelper.getParentLayer(description))
                    || !checkDecoratorPrecondition(element.getTarget(), (DSemanticDecorator) element.eContainer(), description)) {
                it.remove();
            }
        }
    }

    /**
     * Refresh a {@link DNode}.
     * 
     * @param newNode
     *            node to be refreshed.
     */
    protected void refresh(final DNode newNode) {
        final DSemanticDecorator container = (DSemanticDecorator) newNode.eContainer();
        if (container != null) {
            NodeStyleDescription nodeStyleDescription = null;
            NodeMapping nodeMapping = newNode.getActualMapping();
            if (hasSafeTarget(newNode) && hasSafeTarget(container)) {
                nodeStyleDescription = (NodeStyleDescription) this.mappingHelper.getBestStyleDescription(nodeMapping, newNode.getTarget(), newNode, container.getTarget(), diagram);
            }
            if (nodeStyleDescription != null) {
                if (newNode.getResizeKind() != nodeStyleDescription.getResizeKind()) {
                    newNode.setResizeKind(nodeStyleDescription.getResizeKind());
                }

                // Don't set width and height here for Ellipse, Lozenge, Square
                // or WorkspaceImage styles
                boolean customSizeRefresh = nodeStyleDescription instanceof EllipseNodeDescription || nodeStyleDescription instanceof LozengeNodeDescription
                        || nodeStyleDescription instanceof SquareDescription || nodeStyleDescription instanceof WorkspaceImageDescription;

                if (!StringUtil.isEmpty(nodeStyleDescription.getSizeComputationExpression()) && !customSizeRefresh) {
                    styleHelper.setComputedSize(newNode, nodeStyleDescription);
                }

                refreshLabel(newNode, nodeStyleDescription);
                refreshTooltip(newNode, nodeStyleDescription);
                refreshStyle(newNode, nodeMapping);
            }
        }

        // clean decorations
        cleanDecoration(newNode);
        refreshSemanticElements(newNode, newNode.getDiagramElementMapping());
    }

    private void refreshLabel(final DDiagramElement dde, LabelStyleDescription labelStyleDescription) {
        if (!StringUtil.isEmpty(labelStyleDescription.getLabelExpression())) {
            String computedLabel = computeLabel(dde, labelStyleDescription);
            if (!("".equals(dde.getName()) && computedLabel == null) && !StringUtil.equals(dde.getName(), computedLabel)) { //$NON-NLS-1$
                // This is a workaround for a CDO issue in legacy mode
                // (https://bugs.eclipse.org/bugs/show_bug.cgi?id=404152)
                dde.setName(computedLabel);
            }
        }
    }

    private void refreshTooltip(final DDiagramElement elt, final TooltipStyleDescription style) {
        if (!StringUtil.isEmpty(style.getTooltipExpression())) {
            final String oldValue = elt.getTooltipText();
            final String newValue = computeTooltip(elt, style);
            if (!Objects.equal(newValue, oldValue)) {
                elt.setTooltipText(newValue);
            }
        }
    }

    /**
     * Refreshes a node style.
     * 
     * @param node
     *            Node which style is to be refreshed.
     * @param mapping
     *            Mapping that is to be used to compute the best style for this
     *            node.
     */
    public void refreshStyle(final AbstractDNode node, final AbstractNodeMapping mapping) {
        EObject containerVariable = null;
        if (node.eContainer() != null) {
            this.interpreter.setVariable(IInterpreterSiriusVariables.CONTAINER_VIEW, node.eContainer());
            if (node.eContainer() instanceof DSemanticDecorator) {
                containerVariable = ((DSemanticDecorator) node.eContainer()).getTarget();
                this.interpreter.setVariable(IInterpreterSiriusVariables.CONTAINER, containerVariable);

            }
        }
        this.interpreter.setVariable(IInterpreterSiriusVariables.VIEWPOINT, this.diagram);
        this.interpreter.setVariable(IInterpreterSiriusVariables.DIAGRAM, this.diagram);
        this.interpreter.setVariable(IInterpreterSiriusVariables.VIEW, node);

        StyleDescription bestStyleDescription = null;
        if (hasSafeTarget(node)) {
            bestStyleDescription = this.mappingHelper.getBestStyleDescription(mapping, node.getTarget(), node, containerVariable, diagram);
        }
        Style style = node.getStyle();
        if (style != null) {
            Style bestStyle = this.mappingHelper.getBestStyle(mapping, node.getTarget(), node, containerVariable, diagram);
            // In case the current Style is a customized
            if (bestStyleDescription != null && !isSameDescription(bestStyleDescription, style, bestStyle)) {
                final Style currentStyle = style;
                if (isCustomizedWorkspaceImageWorkspacePath(currentStyle)) {
                    styleHelper.refreshStyle(style);
                } else {
                    styleHelper.setAndRefreshStyle(node, currentStyle, styleHelper.createStyle(bestStyleDescription));
                }
            } else {
                styleHelper.refreshStyle(style);
            }
        } else {
            styleHelper.setAndRefreshStyle(node, null, styleHelper.createStyle(bestStyleDescription));
        }

        this.interpreter.unSetVariable(IInterpreterSiriusVariables.VIEW);
        this.interpreter.unSetVariable(IInterpreterSiriusVariables.DIAGRAM);
        this.interpreter.unSetVariable(IInterpreterSiriusVariables.VIEWPOINT);
        if (node.eContainer() != null) {
            this.interpreter.unSetVariable(IInterpreterSiriusVariables.CONTAINER_VIEW);
            if (node.eContainer() instanceof DSemanticDecorator) {
                this.interpreter.unSetVariable(IInterpreterSiriusVariables.CONTAINER);
            }
        }
    }

    private boolean isCustomizedWorkspaceImageWorkspacePath(Style style) {
        boolean isCustomizedWorkspaceImageWorkspacePath = false;
        if (style instanceof WorkspaceImage) {
            WorkspaceImage workspaceImage = (WorkspaceImage) style;
            isCustomizedWorkspaceImageWorkspacePath = workspaceImage.getCustomFeatures().contains(DiagramPackage.Literals.WORKSPACE_IMAGE__WORKSPACE_PATH.getName());
        }
        return isCustomizedWorkspaceImageWorkspacePath;
    }

    /**
     * 
     * @param bestStyleDescription
     *            the description
     * @param style
     *            the current style
     * @param bestStyle
     *            the best style
     * @return if the description is the same type as the style
     */
    private boolean isSameDescription(StyleDescription bestStyleDescription, Style style, Style bestStyle) {
        return bestStyleDescription == style.getDescription() && bestStyle.eClass().equals(style.eClass());
    }

    /**
     * Refreshes an edge style.
     * 
     * @param edge
     *            Edge which style is to be refreshed.
     * @param mapping
     *            Mapping that is to be used to compute the best style for this
     *            node.
     * @param parentDiagram
     *            the parent diagram of the edge
     */
    public void refreshStyle(final DEdge edge, final EdgeMapping mapping, final DDiagram parentDiagram) {
        this.interpreter.setVariable(IInterpreterSiriusVariables.DIAGRAM, this.diagram);
        this.interpreter.setVariable(IInterpreterSiriusVariables.VIEW, edge);
        this.interpreter.setVariable(IInterpreterSiriusVariables.SOURCE_VIEW, edge.getSourceNode());
        this.interpreter.setVariable(IInterpreterSiriusVariables.TARGET_VIEW, edge.getTargetNode());

        EObject containerVariable = null;
        if (edge.eContainer() instanceof DSemanticDecorator) {
            containerVariable = ((DSemanticDecorator) edge.eContainer()).getTarget();
        }
        StyleDescription bestStyleDescription = null;
        if (edge.getTarget() != null) {
            bestStyleDescription = this.mappingHelper.getBestStyleDescription(mapping, edge.getTarget(), edge, containerVariable, parentDiagram);
        }
        if (bestStyleDescription != null && bestStyleDescription != edge.getStyle().getDescription()) {
            final Style currentStyle = edge.getStyle();
            styleHelper.setAndRefreshStyle(edge, currentStyle, styleHelper.createStyle(bestStyleDescription));
        } else if (edge.getStyle() != null) {
            styleHelper.refreshStyle(edge.getStyle());
        }

        this.interpreter.unSetVariable(IInterpreterSiriusVariables.DIAGRAM);
        this.interpreter.unSetVariable(IInterpreterSiriusVariables.VIEW);
        this.interpreter.unSetVariable(IInterpreterSiriusVariables.SOURCE_VIEW);
        this.interpreter.unSetVariable(IInterpreterSiriusVariables.TARGET_VIEW);
    }

    /**
     * Creates a node style.
     * 
     * @param node
     *            node to refresh.
     * @param mapping
     *            mapping to use to compute the style.
     */
    public void createStyle(final AbstractDNode node, final AbstractNodeMapping mapping) {
        EObject containerVariable = null;
        if (node.eContainer() != null) {
            this.interpreter.setVariable(IInterpreterSiriusVariables.CONTAINER_VIEW, node.eContainer());
            if (node.eContainer() instanceof DSemanticDecorator) {
                containerVariable = ((DSemanticDecorator) node.eContainer()).getTarget();
                this.interpreter.setVariable(IInterpreterSiriusVariables.CONTAINER, containerVariable);
            }
        }
        this.interpreter.setVariable(IInterpreterSiriusVariables.VIEWPOINT, this.diagram);
        this.interpreter.setVariable(IInterpreterSiriusVariables.DIAGRAM, this.diagram);
        this.interpreter.setVariable(IInterpreterSiriusVariables.VIEW, node);

        this.mappingHelper.affectAndRefreshStyle(mapping, node, node.getTarget(), containerVariable, diagram);

        if (node.eContainer() != null) {
            this.interpreter.unSetVariable(IInterpreterSiriusVariables.CONTAINER_VIEW);
            if (node.eContainer() instanceof DSemanticDecorator) {
                this.interpreter.unSetVariable(IInterpreterSiriusVariables.CONTAINER);
            }
        }
        this.interpreter.unSetVariable(IInterpreterSiriusVariables.VIEW);
        this.interpreter.unSetVariable(IInterpreterSiriusVariables.DIAGRAM);
        this.interpreter.unSetVariable(IInterpreterSiriusVariables.VIEWPOINT);
    }

    /**
     * Creates an edge style.
     * 
     * @param edge
     *            edge to refresh.
     * 
     * @param mapping
     *            mapping to use to compute the new style.
     * @param parentDiagram
     *            the parent diagram of the edge
     */
    public void createStyle(final DEdge edge, final EdgeMapping mapping, final DDiagram parentDiagram) {
        this.interpreter.setVariable(IInterpreterSiriusVariables.DIAGRAM, this.diagram);
        this.interpreter.setVariable(IInterpreterSiriusVariables.VIEW, edge);
        this.interpreter.setVariable(IInterpreterSiriusVariables.SOURCE_VIEW, edge.getSourceNode());
        this.interpreter.setVariable(IInterpreterSiriusVariables.TARGET_VIEW, edge.getTargetNode());

        if (edge.getStyle() == null || edge.getStyle().getCustomFeatures().isEmpty()) {
            EObject containerVariable = null;
            if (edge.eContainer() instanceof DSemanticDecorator) {
                containerVariable = ((DSemanticDecorator) edge.eContainer()).getTarget();
            }
            this.mappingHelper.affectAndRefreshStyle(mapping, edge, edge.getTarget(), containerVariable, parentDiagram);
        } else {
            if (edge.getStyle().getCustomFeatures().isEmpty()) {
                Option<EdgeStyle> noPreviousStyle = Options.newNone();
                styleHelper.refreshStyle(edge.getOwnedStyle(), noPreviousStyle);
            } else {
                styleHelper.refreshStyle(edge.getOwnedStyle(), Options.newSome(edge.getOwnedStyle()));
            }
        }

        this.interpreter.unSetVariable(IInterpreterSiriusVariables.DIAGRAM);
        this.interpreter.unSetVariable(IInterpreterSiriusVariables.VIEW);
        this.interpreter.unSetVariable(IInterpreterSiriusVariables.SOURCE_VIEW);
        this.interpreter.unSetVariable(IInterpreterSiriusVariables.TARGET_VIEW);
    }

    private String computeLabel(final DDiagramElement view, final EObject descriptionObject) {
        String result = IInterpreterMessages.DEFAULT_NAME_ON_FACTORY_EXCEPTION;

        if (descriptionObject instanceof BasicLabelStyleDescription) {
            result = DiagramElementMappingHelper.computeLabel(view, (BasicLabelStyleDescription) descriptionObject, this.diagram, interpreter);
        }

        return result;
    }

    private String computeTooltip(final DSemanticDecorator view, final EObject descriptionObject) {
        String result = StylePackage.eINSTANCE.getTooltipStyleDescription_TooltipExpression().getDefaultValueLiteral();

        if (descriptionObject instanceof TooltipStyleDescription) {
            String tooltipExpression = ((TooltipStyleDescription) descriptionObject).getTooltipExpression();

            try {
                interpreter.setVariable(IInterpreterSiriusVariables.VIEW, view);
                result = interpreter.evaluateString(view.getTarget(), tooltipExpression);
            } catch (final EvaluationException e) {
                RuntimeLoggerManager.INSTANCE.error(descriptionObject, StylePackage.eINSTANCE.getTooltipStyleDescription_TooltipExpression(), e);
            } finally {
                interpreter.unSetVariable(IInterpreterSiriusVariables.VIEW);
            }
        }

        return result;
    }

    /**
     * Create the edge path if needed path.
     * 
     * @param edge
     *            edge to update.
     * @param mapping
     *            the edge mapping used for the path computing.
     * @param mappingsToEdgeTargets
     *            map for the Mapping eobject to view elements.
     */
    public void updatePath(final DEdge edge, final EdgeMapping mapping, final Map<DiagramElementMapping, Collection<EdgeTarget>> mappingsToEdgeTargets) {
        if (mapping.getPathExpression() != null && !StringUtil.isEmpty(mapping.getPathExpression()) && mapping.getPathNodeMapping() != null) {

            List<EObject> pathSemanticCandidates = Collections.<EObject> emptyList();
            // variables.
            interpreter.setVariable(IInterpreterSiriusVariables.VIEWPOINT, diagram);
            interpreter.setVariable(IInterpreterSiriusVariables.DIAGRAM, diagram);
            interpreter.setVariable(IInterpreterSiriusVariables.ELEMENT, edge.getTarget());
            if (edge.getSourceNode() instanceof DSemanticDecorator) {
                interpreter.setVariable(IInterpreterSiriusVariables.SOURCE, ((DSemanticDecorator) edge.getSourceNode()).getTarget());
            }
            if (edge.getTargetNode() instanceof DSemanticDecorator) {
                interpreter.setVariable(IInterpreterSiriusVariables.TARGET, ((DSemanticDecorator) edge.getTargetNode()).getTarget());
            }

            try {
                pathSemanticCandidates = new ArrayList<EObject>(interpreter.evaluateCollection(edge.getTarget(), mapping.getPathExpression()));
            } catch (final EvaluationException e) {
                RuntimeLoggerManager.INSTANCE.error(mapping, DescriptionPackage.eINSTANCE.getEdgeMapping_PathExpression(), e);
            } finally {
                interpreter.unSetVariable(IInterpreterSiriusVariables.VIEWPOINT);
                interpreter.unSetVariable(IInterpreterSiriusVariables.DIAGRAM);
                interpreter.unSetVariable(IInterpreterSiriusVariables.ELEMENT);
                interpreter.unSetVariable(IInterpreterSiriusVariables.SOURCE);
                interpreter.unSetVariable(IInterpreterSiriusVariables.TARGET);
            }

            final Map<EObject, EdgeTarget> availableElements = getAvailableElements(mappingsToEdgeTargets, mapping.getPathNodeMapping());

            final Collection<EObject> semanticAvailableElements = availableElements.keySet();

            EList<EdgeTarget> newPath = new BasicEList<EdgeTarget>();

            for (final EObject pathSemanticCandidate : pathSemanticCandidates) {
                if (semanticAvailableElements.contains(pathSemanticCandidate)) {
                    newPath.add(availableElements.get(pathSemanticCandidate));
                }
            }

            if (!newPath.isEmpty() && !edge.getPath().equals(newPath)) {
                edge.getPath().clear();
                edge.getPath().addAll(newPath);
            }
        }
    }

    private Map<EObject, EdgeTarget> getAvailableElements(final Map<DiagramElementMapping, Collection<EdgeTarget>> mappingsToEdgeTargets, final Collection<AbstractNodeMapping> mappings) {
        final Map<EObject, EdgeTarget> semanticToEdgeTargets = new HashMap<EObject, EdgeTarget>();
        for (final DiagramElementMapping availableMapping : mappings) {
            final Collection<EdgeTarget> edgeTargets = mappingsToEdgeTargets.get(availableMapping);
            if (edgeTargets != null) {
                for (final EdgeTarget edgeTarget : edgeTargets) {
                    if (edgeTarget instanceof DSemanticDecorator) {
                        semanticToEdgeTargets.put(((DSemanticDecorator) edgeTarget).getTarget(), edgeTarget);
                    }
                }
            }
        }
        return semanticToEdgeTargets;
    }

    /**
     * Add a decoration to a DdiagramElement.
     * 
     * @param element
     *            element to decorate
     * @param decorationDescription
     *            description of the decoration
     */
    public void addDecoration(final DDiagramElement element, final DecorationDescription decorationDescription) {
        for (final Decoration decoration : new ArrayList<Decoration>(element.getDecorations())) {
            if (EcoreUtil.equals(decorationDescription, decoration.getDescription())) {
                return;
            }
        }
        // new decoration
        if (checkDecoratorPrecondition(element.getTarget(), (DSemanticDecorator) element.eContainer(), decorationDescription)) {
            final Decoration decoration = ViewpointFactory.eINSTANCE.createDecoration();
            decoration.setDescription(decorationDescription);
            element.getDecorations().add(decoration);
        }
    }

    private boolean checkDecoratorPrecondition(final EObject semantic, final DSemanticDecorator container, final DecorationDescription decorationDescription) {
        DslCommonPlugin.PROFILER.startWork(SiriusTasksKey.CHECK_PRECONDITION_KEY);
        boolean result = false;
        if (decorationDescription != null && !decorationDescription.eIsProxy()) {
            result = true;
            final String preconditionExpression = decorationDescription.getPreconditionExpression();
            if (!StringUtil.isEmpty(preconditionExpression)) {
                this.interpreter.setVariable(IInterpreterSiriusVariables.CONTAINER_VIEW, container);
                this.interpreter.setVariable(IInterpreterSiriusVariables.CONTAINER, container != null ? container.getTarget() : null);
                this.interpreter.setVariable(IInterpreterSiriusVariables.VIEWPOINT, this.diagram);
                this.interpreter.setVariable(IInterpreterSiriusVariables.DIAGRAM, this.diagram);
                try {
                    result = interpreter.evaluateBoolean(semantic, preconditionExpression);
                } catch (final EvaluationException e) {
                    RuntimeLoggerManager.INSTANCE.error(decorationDescription, org.eclipse.sirius.viewpoint.description.DescriptionPackage.eINSTANCE.getDecorationDescription_PreconditionExpression(),
                            e);
                }
                this.interpreter.unSetVariable(IInterpreterSiriusVariables.CONTAINER_VIEW);
                this.interpreter.unSetVariable(IInterpreterSiriusVariables.CONTAINER);
                this.interpreter.unSetVariable(IInterpreterSiriusVariables.VIEWPOINT);
                this.interpreter.unSetVariable(IInterpreterSiriusVariables.DIAGRAM);
            }
        }
        DslCommonPlugin.PROFILER.stopWork(SiriusTasksKey.CHECK_PRECONDITION_KEY);
        return result;
    }

    private void refreshSemanticElements(final DDiagramElement element, final DiagramElementMapping mapping) {
        DiagramElementMappingHelper.refreshSemanticElements(mapping, element, this.interpreter);
    }

    /**
     * Check if the target of this decorator is not null and is in a eResource.
     * 
     * @param decorator
     *            The decorator to check
     * @return true if the target is OK, false otherwise.
     */
    private boolean hasSafeTarget(DSemanticDecorator semDec) {
        EObject target = semDec.getTarget();
        return target != null && (target.eContainer() != null || target.eResource() != null);
    }
}
