/*******************************************************************************
 * Copyright (c) 2010, 2015 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.tree.business.internal.dialect;

import java.text.MessageFormat;
import java.util.Collection;
import java.util.Set;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.sirius.business.api.dialect.AbstractRepresentationDialectServices;
import org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionQuery;
import org.eclipse.sirius.business.api.query.DRepresentationElementQuery;
import org.eclipse.sirius.business.api.query.EObjectQuery;
import org.eclipse.sirius.business.api.query.IdentifiedElementQuery;
import org.eclipse.sirius.business.api.session.CustomDataConstants;
import org.eclipse.sirius.business.api.session.Session;
import org.eclipse.sirius.business.api.session.SessionManager;
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.util.StringUtil;
import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
import org.eclipse.sirius.tools.api.command.DCommand;
import org.eclipse.sirius.tools.api.interpreter.InterpreterRegistry;
import org.eclipse.sirius.tools.api.interpreter.InterpreterUtil;
import org.eclipse.sirius.tree.DTree;
import org.eclipse.sirius.tree.DTreeElement;
import org.eclipse.sirius.tree.DTreeElementSynchronizer;
import org.eclipse.sirius.tree.DTreeItem;
import org.eclipse.sirius.tree.TreeFactory;
import org.eclipse.sirius.tree.business.api.interaction.DTreeUserInteraction;
import org.eclipse.sirius.tree.business.internal.dialect.common.viewpoint.GlobalContext;
import org.eclipse.sirius.tree.business.internal.dialect.description.TreeInterpretedExpressionQuery;
import org.eclipse.sirius.tree.business.internal.refresh.DTreeElementSynchronizerSpec;
import org.eclipse.sirius.tree.description.TreeDescription;
import org.eclipse.sirius.tree.tools.internal.Messages;
import org.eclipse.sirius.tree.tools.internal.command.TreeCommandFactory;
import org.eclipse.sirius.viewpoint.DRepresentation;
import org.eclipse.sirius.viewpoint.DSemanticDecorator;
import org.eclipse.sirius.viewpoint.SiriusPlugin;
import org.eclipse.sirius.viewpoint.description.RepresentationDescription;
import org.eclipse.sirius.viewpoint.description.RepresentationExtensionDescription;
import org.eclipse.sirius.viewpoint.description.Viewpoint;

import com.google.common.collect.Sets;

/**
 * The {@link AbstractRepresentationDialectServices} implementation for the Tree
 * dialect.
 * 
 * @author pcdavid
 */
public class TreeDialectServices extends AbstractRepresentationDialectServices {
    @Override
    protected boolean isSupported(RepresentationDescription description) {
        return description instanceof TreeDescription;
    }

    @Override
    protected boolean isSupported(DRepresentation representation) {
        return representation instanceof DTree;
    }

    @Override
    public DRepresentation createRepresentation(String name, EObject semantic, RepresentationDescription description, IProgressMonitor monitor) {
        DTree tree = null;
        try {
            monitor.beginTask(MessageFormat.format(Messages.TreeDialectServices_createTree, name), 11);
            monitor.subTask(MessageFormat.format(Messages.TreeDialectServices_createTree, name));
            final Session session = SessionManager.INSTANCE.getSession(semantic);
            final EditingDomain domain = session.getTransactionalEditingDomain();
            /*
             * Let's check if the description resource is in the session
             * resource set.
             */
            /*
             * FIXME we should certainly not remove from the previous resource
             * set. The viewpoint registry for instance has is own resource set
             * !
             */
            final Resource descriptionRes = description.eResource();
            if (!domain.getResourceSet().getResources().contains(descriptionRes)) {
                domain.getResourceSet().getResources().add(descriptionRes);
            }

            tree = TreeFactory.eINSTANCE.createDTree();
            tree.setName(name);
            tree.setDescription((TreeDescription) description);
            tree.setTarget(semantic);
            monitor.worked(1);

            refresh(tree, new SubProgressMonitor(monitor, 10));
        } finally {
            monitor.done();
        }
        return tree;
    }

    /**
     * {@inheritDoc}
     */
    public void initRepresentations(Viewpoint vp, EObject semantic) {
        super.initRepresentations(semantic, vp, TreeDescription.class);
    }

    @Override
    public void initRepresentations(Viewpoint vp, EObject semantic, IProgressMonitor monitor) {
        super.initRepresentations(semantic, vp, TreeDescription.class, monitor);
    }

    @Override
    protected <T extends RepresentationDescription> void initRepresentationForElement(T representationDescription, EObject semanticElement, IProgressMonitor monitor) {
        if (representationDescription instanceof TreeDescription) {
            TreeDescription treeDescription = (TreeDescription) representationDescription;
            if (shouldInitializeRepresentation(semanticElement, treeDescription, treeDescription.getDomainClass())) {

                final ModelAccessor modelAccessor = SiriusPlugin.getDefault().getModelAccessorRegistry().getModelAccessor(semanticElement);
                final TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(semanticElement);

                if (modelAccessor.eInstanceOf(semanticElement, treeDescription.getDomainClass())) {
                    boolean canCreate = true;
                    if (treeDescription.getPreconditionExpression() != null && !StringUtil.isEmpty(treeDescription.getPreconditionExpression())) {
                        try {
                            canCreate = InterpreterUtil.getInterpreter(semanticElement).evaluateBoolean(semanticElement, treeDescription.getPreconditionExpression());
                        } catch (final EvaluationException e) {
                            canCreate = false;
                        }
                    }
                    if (canCreate) {
                        try {
                            monitor.beginTask(MessageFormat.format(Messages.TreeDialectServices_initializeTree, new IdentifiedElementQuery(representationDescription).getLabel()), 1);
                            final TreeCommandFactory treeCommandFactory = new TreeCommandFactory(domain);
                            treeCommandFactory.setModelAccessor(modelAccessor);
                            DCommand command = treeCommandFactory.buildCreateTreeFromDescription(treeDescription, semanticElement, new SubProgressMonitor(monitor, 1));
                            domain.getCommandStack().execute(command);
                        } finally {
                            monitor.done();
                        }
                    }
                }
            }
        }
    }

    @Override
    public DRepresentation copyRepresentation(final DRepresentation representation, final String name, final Session session, final IProgressMonitor monitor) {
        DRepresentation newRepresentation = super.copyRepresentation(representation, name, session, monitor);
        /* associate the one */
        session.getServices().putCustomData(CustomDataConstants.DREPRESENTATION, ((DSemanticDecorator) representation).getTarget(), newRepresentation);
        return newRepresentation;
    }

    /**
     * Initializes the Representation described by the given description,
     * according the the given target value.
     * 
     * @param description
     *            the RepresentationDescription describing the representation to
     *            initialize
     * @param target
     *            the semantic target to use for initialize this representation
     */
    protected void initRepresentation(RepresentationDescription description, EObject target) {
        // TODO
    }

    @Override
    public void refresh(DRepresentation representation, boolean fullRefresh, IProgressMonitor monitor) {
        try {
            monitor.beginTask(Messages.TreeDialectServices_treeRefresh, 1);
            if (canRefresh(representation)) {
                refreshTree((DTree) representation, fullRefresh, monitor);
            }
        } finally {
            monitor.done();
        }
    }

    @Override
    public RepresentationDescription getDescription(DRepresentation representation) {
        if (isSupported(representation)) {
            return ((DTree) representation).getDescription();
        } else {
            return null;
        }
    }

    private void refreshTree(DTree tree, boolean fullRefresh, IProgressMonitor monitor) {
        Session session = SessionManager.INSTANCE.getSession(tree.getTarget());
        IInterpreter interpreter = SiriusPlugin.getDefault().getInterpreterRegistry().getInterpreter(tree.getTarget());
        InterpreterRegistry.prepareImportsFromSession(interpreter, session);
        ModelAccessor accessor = SiriusPlugin.getDefault().getModelAccessorRegistry().getModelAccessor(tree.getTarget());

        DTreeUserInteraction interaction = new DTreeUserInteraction(tree, new GlobalContext(accessor, session.getInterpreter(), session.getSemanticResources()));
        interaction.refreshContent(fullRefresh, new SubProgressMonitor(monitor, 1));

    }

    @Override
    public boolean canCreate(EObject semantic, RepresentationDescription desc) {
        boolean result = false;
        if (semantic != null && isSupported(desc)) {
            TreeDescription treeDesc = (TreeDescription) desc;
            ModelAccessor accessor = SiriusPlugin.getDefault().getModelAccessorRegistry().getModelAccessor(semantic);
            if (accessor != null) {
                result = checkDomainClass(accessor, semantic, treeDesc.getDomainClass());
            }
            result = result && checkPrecondition(semantic, treeDesc.getPreconditionExpression());
        }
        return result;
    }

    @Override
    public IInterpretedExpressionQuery createInterpretedExpressionQuery(EObject target, EStructuralFeature feature) {
        return new TreeInterpretedExpressionQuery(target, feature);
    }

    @Override
    public boolean handles(RepresentationDescription representationDescription) {
        return representationDescription instanceof TreeDescription;
    }

    @Override
    public boolean handles(RepresentationExtensionDescription representationExtensionDescription) {
        return false;
    }

    @Override
    public void refreshImpactedElements(DRepresentation representation, Collection<Notification> notifications, IProgressMonitor monitor) {
        try {
            monitor.beginTask(Messages.DTreeUserInteraction_treeRefresh, 10);
            DTree tree = (DTree) representation;
            IInterpreter interpreter = SiriusPlugin.getDefault().getInterpreterRegistry().getInterpreter(tree.getTarget());
            ModelAccessor accessor = SiriusPlugin.getDefault().getModelAccessorRegistry().getModelAccessor(representation);

            Set<DTreeElement> dTreeElements = getTreeElementsToRefresh(notifications, tree);
            monitor.worked(2);
            DTreeElementSynchronizer synchronizer = new DTreeElementSynchronizerSpec(interpreter, accessor);
            IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 8);
            try {
                subMonitor.beginTask(Messages.TreeDialectServices_refreshImpactedElements, dTreeElements.size());
                for (DTreeElement dTreeElement : dTreeElements) {
                    if (dTreeElement instanceof DTreeItem) {
                        synchronizer.refresh((DTreeItem) dTreeElement);
                    }
                    subMonitor.worked(1);
                }
            } finally {
                subMonitor.done();
            }
        } finally {
            monitor.done();
        }
    }

    private Set<DTreeElement> getTreeElementsToRefresh(Collection<Notification> notifications, DTree tree) {
        Set<DTreeElement> treeElementsToRefresh = Sets.newHashSet();
        Session session = new org.eclipse.sirius.business.api.query.EObjectQuery(tree.getTarget()).getSession();
        if (session != null) {
            ECrossReferenceAdapter xref = session.getSemanticCrossReferencer();
            // Deal with each notifier only one time.
            Set<EObject> alreadyDoneNotifiers = Sets.newHashSet();
            for (Notification notification : notifications) {
                Object notifier = notification.getNotifier();
                if (notifier instanceof EObject) {
                    EObject eObjectNotifier = (EObject) notifier;
                    if (alreadyDoneNotifiers.add(eObjectNotifier)) {
                        treeElementsToRefresh.addAll(getTreeElementsToRefresh(eObjectNotifier, tree, xref));
                    }
                }
            }
        }
        return treeElementsToRefresh;
    }

    private Set<DTreeElement> getTreeElementsToRefresh(EObject notifier, DTree tree, ECrossReferenceAdapter xref) {
        Set<DTreeElement> treeElementsToRefresh = Sets.newHashSet();
        Collection<EObject> inverseReferencers = new EObjectQuery(notifier, xref).getInverseReferences(REPRESENTATION_ELEMENTS_INVERSE_REFERENCES);
        for (EObject inverseReferencer : inverseReferencers) {
            if (inverseReferencer instanceof DTreeElement) {
                DTreeElement treeElement = (DTreeElement) inverseReferencer;
                if (isContainedWithinCurrentTree(treeElement, tree)) {
                    treeElementsToRefresh.add(treeElement);
                }
            }
        }
        return treeElementsToRefresh;
    }

    private boolean isContainedWithinCurrentTree(DTreeElement treeElement, DTree tree) {
        return tree == new DRepresentationElementQuery(treeElement).getParentRepresentation();
    }
}
