/*******************************************************************************
 * Copyright (c) 2011, 2018 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.ui.tools.internal.views.common.modelingproject.manager;

import java.text.MessageFormat;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.util.URI;
import org.eclipse.sirius.business.api.modelingproject.ModelingProject;
import org.eclipse.sirius.business.api.resource.strategy.ResourceStrategyRegistry;
import org.eclipse.sirius.business.api.session.DefaultLocalSessionCreationOperation;
import org.eclipse.sirius.business.api.session.Session;
import org.eclipse.sirius.business.api.session.SessionListener;
import org.eclipse.sirius.business.api.session.SessionManager;
import org.eclipse.sirius.business.api.session.SessionManagerListener;
import org.eclipse.sirius.business.internal.modelingproject.marker.ModelingMarker;
import org.eclipse.sirius.business.internal.query.ModelingProjectQuery;
import org.eclipse.sirius.ext.base.Option;
import org.eclipse.sirius.tools.api.command.semantic.AddSemanticResourceCommand;
import org.eclipse.sirius.ui.tools.api.project.ModelingProjectManager;
import org.eclipse.sirius.ui.tools.internal.views.common.modelingproject.OpenRepresentationsFileJob;
import org.eclipse.sirius.ui.tools.internal.views.modelexplorer.resourcelistener.ISessionFileLoadingListener;
import org.eclipse.sirius.viewpoint.SiriusPlugin;
import org.eclipse.sirius.viewpoint.provider.Messages;
import org.eclipse.sirius.viewpoint.provider.SiriusEditPlugin;

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

/**
 * A manager for modeling projects.
 *
 * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a>
 */
public class ModelingProjectManagerImpl implements ModelingProjectManager {

    /** The old Viewpoint nature id. */
    private static final String VIEWPOINT_MODELING_PROJECT_NATURE_ID = "fr.obeo.dsl.viewpoint.nature.modelingproject"; //$NON-NLS-1$

    private final SessionManagerListener sessionManagerListener = new SessionManagerListener.Stub() {
        @Override
        public void notify(Session updated, int notification) {
            if (notification == SessionListener.OPENING) {
                // No need to at it again to the sessionFileLoading list because
                // we add it during the starting of the load
                // ModelingProjectManager.loadAndOpenSession().
            } else if (notification == SessionListener.OPENED) {
                sessionFileLoading.remove(updated.getSessionResource().getURI());
            } else if (notification == SessionListener.CLOSED) {
                // make sure that the session is re-openable if CLOSED
                // That is necessary because the session may not have opened
                // correctly and the SessionListener.OPENED may not have been
                // sent.
                sessionFileLoading.remove(updated.getSessionResource().getURI());
            }
        }
    };

    private Predicate<URI> isAlreadyLoadedPredicate = new Predicate<URI>() {
        @Override
        public boolean apply(URI representationsFileURI) {
            return isAlreadyLoaded(representationsFileURI);
        }
    };

    /**
     * Set of representations files that are currently loading. There can be only one representations file in loading at
     * same time. However there may be many waiting to be loaded.
     */
    private Set<URI> sessionFileLoading = Sets.newHashSet();

    /**
     * Avoid instantiation.
     */
    protected ModelingProjectManagerImpl() {
    }

    /**
     * Default initialization of a {@link ModelingProjectManagerImpl}.
     *
     * @return a new instance of {@link ModelingProjectManagerImpl}.
     */
    public static ModelingProjectManagerImpl init() {
        return new ModelingProjectManagerImpl();
    }

    @Override
    public void loadAndOpenRepresentationsFile(final URI representationsFileURI) {
        loadAndOpenRepresentationsFiles(Lists.newArrayList(representationsFileURI), false);
    }

    @Override
    public void loadAndOpenRepresentationsFile(final URI representationsFileURI, boolean user) {
        loadAndOpenRepresentationsFiles(Lists.newArrayList(representationsFileURI), user);
    }

    @Override
    public void loadAndOpenRepresentationsFiles(final List<URI> representationsFilesURIs) {
        loadAndOpenRepresentationsFiles(representationsFilesURIs, false);
    }

    /**
     * Load and open representations files by scheduling a new job.
     * 
     * @param representationsFilesURIs
     *            The URIs of the representations files to open.
     * @param user
     *            <code>true</code> if this job is a user-initiated job, and <code>false</code> otherwise.
     * @throws CoreException
     *             Only useful in case of <code>alreadyInUserWorkspaceModifyOperation</code> is true.
     */
    private void loadAndOpenRepresentationsFiles(final List<URI> representationsFilesURIs, boolean user) {
        try {
            loadAndOpenRepresentationsFiles(representationsFilesURIs, false, false);
        } catch (CoreException e) {
            // Nothing do to, it can not happen as
            // <code>alreadyInUserWorkspaceModifyOperation</code> is false.
        }
    }

    /**
     * Load and open representations files by scheduling a new job or by launching directly the job (when
     * <code>alreadyInUserWorkspaceModifyOperation</code> is true).
     * 
     * @param representationsFilesURIs
     *            The URIs of the representations files to open.
     * @param user
     *            <code>true</code> if this job is a user-initiated job, and <code>false</code> otherwise.
     * @param alreadyInUserWorkspaceModifyOperation
     *            true if the loading and opening of representations files already occurs in a WorkspaceModifyOperation
     *            launches by user.
     * @throws CoreException
     *             Only useful in case of <code>alreadyInUserWorkspaceModifyOperation</code> is true.
     */
    private void loadAndOpenRepresentationsFiles(final List<URI> representationsFilesURIs, boolean user, boolean alreadyInUserWorkspaceModifyOperation) throws CoreException {
        // Add the specific sessions listener (if not already added).
        SessionManager.INSTANCE.addSessionsListener(sessionManagerListener);

        // List only the representations files that are not already loaded or
        // that are not currently in loading.
        Iterator<URI> representationsFilesURIsToLoadIterator = Iterators.filter(representationsFilesURIs.iterator(),
                Predicates.not(Predicates.or(Predicates.in(sessionFileLoading), isAlreadyLoadedPredicate)));
        if (!representationsFilesURIsToLoadIterator.hasNext()) {
            return;
        }

        // We add the representationsFilesURIs to the list of representations
        // files that are currently loading because the event
        // SessionListener.OPENING comes too late (after loading of the
        // representations file that can be very long).
        List<URI> tempRepresentationsFilesURIs = Lists.newArrayList(representationsFilesURIsToLoadIterator);
        sessionFileLoading.addAll(tempRepresentationsFilesURIs);
        // Launch the silently job to open the representations files
        for (URI representationsFilesURI : tempRepresentationsFilesURIs) {
            if (alreadyInUserWorkspaceModifyOperation) {
                WorkspaceJob job = new OpenRepresentationsFileJob(representationsFilesURI);
                job.setUser(user);
                job.setPriority(Job.SHORT);
                job.runInWorkspace(new NullProgressMonitor());
            } else {
                OpenRepresentationsFileJob.scheduleNewWhenPossible(representationsFilesURI, user);
            }
        }
    }

    /**
     * Check if the representations file is already loaded (known by SessionManager).
     *
     * @param representationsFileURI
     *            The URI of the representations file.
     * @return true if already loaded, false otherwise
     */
    private boolean isAlreadyLoaded(URI representationsFileURI) {
        for (Session session : Collections.unmodifiableCollection(SessionManager.INSTANCE.getSessions())) {
            if (representationsFileURI.equals(session.getSessionResource().getURI())) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void clearCache(URI representationsFileURI) {
        sessionFileLoading.remove(representationsFileURI);
    }

    @Override
    public IProject createNewModelingProject(String projectName, boolean createAndOpenBlankRepresentationsFile, IProgressMonitor monitor) throws CoreException {
        return createNewModelingProject(projectName, null, createAndOpenBlankRepresentationsFile, monitor);
    }

    @Override
    public IProject createNewModelingProject(final String projectName, final IPath projectLocationPath, final boolean createAndOpenBlankRepresentationsFile, IProgressMonitor monitor)
            throws CoreException {
        final IWorkspaceRunnable create = new IWorkspaceRunnable() {
            @Override
            public void run(final IProgressMonitor monitor) throws CoreException {
                try {
                    monitor.beginTask(MessageFormat.format(Messages.ModelingProjectManagerImpl_createModelingProjectTask, projectName), 3);
                    final IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
                    if (!project.exists()) {
                        final IProjectDescription desc = project.getWorkspace().newProjectDescription(projectName);
                        IPath projectLocationPathTemp = projectLocationPath;
                        if (projectLocationPath != null && ResourcesPlugin.getWorkspace().getRoot().getLocation().equals(projectLocationPath)) {
                            projectLocationPathTemp = null;
                        }
                        desc.setLocation(projectLocationPathTemp);
                        String[] natures = { ModelingProject.NATURE_ID };
                        desc.setNatureIds(natures);

                        monitor.subTask(Messages.ModelingProjectManagerImpl_createProjectTask);
                        project.create(desc, new SubProgressMonitor(monitor, 1));
                        monitor.subTask(Messages.ModelingProjectManagerImpl_openProjectTask);
                        project.open(new SubProgressMonitor(monitor, 1));

                        if (createAndOpenBlankRepresentationsFile) {
                            monitor.subTask(Messages.ModelingProjectManagerImpl_createRepresentationFileTask);
                            Session newSession = createLocalRepresentationsFile(project, new SubProgressMonitor(monitor, 1));

                            Set<ISessionFileLoadingListener> sessionFileLoadingListeners = SiriusEditPlugin.getPlugin().getSessionFileLoadingListeners();
                            for (ISessionFileLoadingListener sessionFileLoadingListener : sessionFileLoadingListeners) {
                                sessionFileLoadingListener.notifySessionLoadedFromModelingProject(newSession);
                            }
                        }
                    }
                    if (!project.isOpen()) {
                        project.open(new SubProgressMonitor(monitor, 1));
                    }
                } finally {
                    monitor.done();
                }
            }
        };
        ResourcesPlugin.getWorkspace().run(create, monitor);
        return ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
    }

    @Override
    public void convertToModelingProject(final IProject project, IProgressMonitor monitor) throws CoreException {
        final IWorkspaceRunnable create = new IWorkspaceRunnable() {
            @Override
            public void run(final IProgressMonitor monitor) throws CoreException {
                try {
                    monitor.beginTask(Messages.ModelingProjectManagerImpl_convertToModelingProjectTask, 1);
                    doAddModelingNature(project, new SubProgressMonitor(monitor, 1));
                } finally {
                    monitor.done();
                }

            }
        };
        if (alreadyIsInWorkspaceModificationOperation()) {
            doAddModelingNature(project, monitor);
        } else {
            IWorkspace workspace = ResourcesPlugin.getWorkspace();
            workspace.run(create, ResourcesPlugin.getWorkspace().getRoot(), IWorkspace.AVOID_UPDATE, monitor);
        }
    }

    private boolean alreadyIsInWorkspaceModificationOperation() {
        final Job currentJob = Job.getJobManager().currentJob();
        return currentJob != null && currentJob.getRule() != null;
    }

    @Override
    public void removeModelingNature(final IProject project, IProgressMonitor monitor) throws CoreException {
        final IWorkspaceRunnable create = new IWorkspaceRunnable() {
            @Override
            public void run(final IProgressMonitor monitor) throws CoreException {
                doRemoveModelingNature(project, monitor);
            }
        };
        ResourcesPlugin.getWorkspace().run(create, monitor);
    }

    @Override
    public Session createLocalRepresentationsFile(IProject project, IProgressMonitor monitor) throws CoreException {
        URI representationsURI = URI.createPlatformResourceURI(project.getFullPath().append(ModelingProject.DEFAULT_REPRESENTATIONS_FILE_NAME).toString(), true);

        /* Create a Session from the session model URI */
        org.eclipse.sirius.business.api.session.SessionCreationOperation sessionCreationOperation = new DefaultLocalSessionCreationOperation(representationsURI, monitor);
        sessionCreationOperation.execute();
        return sessionCreationOperation.getCreatedSession();
    }

    /**
     * Add the modeling nature. Open or create the main aird file. Look for semantic resources to add.<br>
     * This method must be called from a WorkspaceModifyOperation with WorkspaceRoot scheduling rule as it modifies the
     * nature of the project.
     *
     * @param project
     *            the project to convert.
     * @param monitor
     *            a {@link IProgressMonitor} to show progression of Modeling Project nature addition
     * @throws CoreException
     *             if something fails.
     */
    protected void doAddModelingNature(IProject project, IProgressMonitor monitor) throws CoreException {
        try {
            monitor.beginTask(Messages.ModelingProjectManagerImpl_addingModelingNatureTask, 3);
            IProjectDescription description = project.getDescription();

            String[] natures = description.getNatureIds();
            if (description.hasNature(ModelingProjectManagerImpl.VIEWPOINT_MODELING_PROJECT_NATURE_ID)) {
                // Replace the old Viewpoint nature
                for (int i = 0; i < natures.length; i++) {
                    if (ModelingProjectManagerImpl.VIEWPOINT_MODELING_PROJECT_NATURE_ID.equals(natures[i])) {
                        natures[i] = ModelingProject.NATURE_ID;
                    }
                }
                description.setNatureIds(natures);
            } else {
                // Add the nature
                String[] newNatures = new String[natures.length + 1];
                System.arraycopy(natures, 0, newNatures, 1, natures.length);
                newNatures[0] = ModelingProject.NATURE_ID;
                description.setNatureIds(newNatures);
            }
            project.setDescription(description, new SubProgressMonitor(monitor, 1));

            // check project
            Option<ModelingProject> optionalModelingProject = ModelingProject.asModelingProject(project);
            if (optionalModelingProject.some()) {
                ModelingProject modelingProject = optionalModelingProject.get();
                try {
                    // See 525466. we set the validity to true in case of DefaultModelingProjectResourceListener that
                    // has set it to false or the representation file will not be created if it does not exist yet.
                    Option<URI> mainRepresentationsFileURI;
                    synchronized (modelingProject) {
                        modelingProject.setValid(true);
                        mainRepresentationsFileURI = modelingProject.getMainRepresentationsFileURI(new SubProgressMonitor(monitor, 1), false, true);
                    }
                    if (mainRepresentationsFileURI != null && mainRepresentationsFileURI.some()) {
                        // Open the session.
                        loadAndOpenRepresentationsFiles(Lists.newArrayList(mainRepresentationsFileURI.get()), true, true);
                    }
                } catch (IllegalArgumentException e) {
                    // Clean existing marker if exists
                    try {
                        project.deleteMarkers(ModelingMarker.MARKER_TYPE, false, IResource.DEPTH_ZERO);
                    } catch (final CoreException ce) {
                        SiriusPlugin.getDefault().getLog().log(ce.getStatus());
                    }
                    if (e.getCause() != null && ModelingProjectQuery.ZERO_REPRESENTATIONS_FILE_FOUND_IN.equals(e.getCause().getMessage())) {
                        // 0 files has been found : create a representation
                        ModelingProjectManager.INSTANCE.createLocalRepresentationsFile(project, new SubProgressMonitor(monitor, 1));
                        // Project has been marked as invalid but now it has a
                        // main representation file, force the computation of
                        // its mainRepresentationFileURI.
                        modelingProject.getMainRepresentationsFileURI(new SubProgressMonitor(monitor, 1), true, true);
                    } else {
                        // Add a marker on this project
                        try {
                            final IMarker marker = project.createMarker(ModelingMarker.MARKER_TYPE);
                            marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
                            marker.setAttribute(IMarker.MESSAGE, e.getMessage());
                        } catch (final CoreException ce) {
                            SiriusPlugin.getDefault().getLog().log(ce.getStatus());
                        }
                        if (e.getCause() != null && ModelingProjectQuery.A_MODELING_PROJECT_MUST_CONTAIN_ONLY_ONE.equals(e.getCause().getMessage())) {
                            // several files have been found : rollback
                            removeModelingNature(project, new SubProgressMonitor(monitor, 1));
                            throw new CoreException(new Status(IStatus.ERROR, SiriusEditPlugin.ID, e.getMessage()));
                        }
                    }
                }

                if (modelingProject.getSession() != null) {
                    // add semantic resources if already existing in the project
                    addSemanticResources(project, modelingProject.getSession(), new SubProgressMonitor(monitor, 1));
                }
            }
        } finally {
            monitor.done();
        }
    }

    /**
     * Remove the modeling nature.
     *
     * @param project
     *            the project to convert.
     * @param monitor
     *            a {@link IProgressMonitor} to show Modeling Project nature removal progression
     * @throws CoreException
     *             if something fails.
     */
    protected void doRemoveModelingNature(IProject project, IProgressMonitor monitor) throws CoreException {
        try {
            monitor.beginTask(Messages.ModelingProjectManagerImpl_removingModelingNatureTask, IProgressMonitor.UNKNOWN);
            IProjectDescription description = project.getDescription();
            String[] natures = description.getNatureIds();
            for (int i = 0; i < natures.length; ++i) {
                if (ModelingProject.NATURE_ID.equals(natures[i])) {
                    // Remove the nature
                    String[] newNatures = new String[natures.length - 1];
                    System.arraycopy(natures, 0, newNatures, 0, i);
                    System.arraycopy(natures, i + 1, newNatures, i, natures.length - i - 1);
                    description.setNatureIds(newNatures);
                    project.setDescription(description, new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN));

                    // remove markers corresponding to modeling projects
                    // Clean existing marker if exists
                    project.deleteMarkers(ModelingMarker.MARKER_TYPE, false, IResource.DEPTH_ZERO);
                    break;
                }
            }
        } finally {
            monitor.done();
        }
    }

    private void addSemanticResources(IContainer container, Session session, IProgressMonitor monitor) throws CoreException {
        try {
            monitor.beginTask(Messages.ModelingProjectManagerImpl_semanticResourcesAdditionTask, 1);
            Command semanticResourcesAdditionCommand = getSemanticResourcesAdditionCommand(container, session, monitor);
            session.getTransactionalEditingDomain().getCommandStack().execute(semanticResourcesAdditionCommand);
        } finally {
            monitor.done();
        }
    }

    private Command getSemanticResourcesAdditionCommand(IContainer container, Session session, IProgressMonitor monitor) throws CoreException {
        CompoundCommand cc = new CompoundCommand();
        if (container != null) {
            for (IResource resource : container.members()) {
                if (resource instanceof IFile) {
                    URI uri = URI.createPlatformResourceURI(resource.getFullPath().toOSString(), true);
                    if (ResourceStrategyRegistry.getInstance().isPotentialSemanticResource(uri) && ResourceStrategyRegistry.getInstance().isLoadableModel(uri, session)) {
                        AddSemanticResourceCommand cmd = new AddSemanticResourceCommand(session, uri, new SubProgressMonitor(monitor, 1));
                        cc.append(cmd);
                    }
                } else if (resource instanceof IContainer) {
                    Command subCc = getSemanticResourcesAdditionCommand((IContainer) resource, session, monitor);
                    if (subCc.canExecute()) {
                        cc.append(subCc);
                    }
                }
            }
        }
        return cc;
    }
}
