/*******************************************************************************
 * Copyright (c) 2009 University of Illinois at Urbana-Champaign 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:
 *     UIUC - Initial API and implementation
 *******************************************************************************/
package org.eclipse.rephraserengine.core.vpg.eclipse;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.MultiRule;
import org.eclipse.rephraserengine.core.vpg.TokenRef;
import org.eclipse.rephraserengine.core.vpg.VPG;
import org.eclipse.rephraserengine.core.vpg.VPGDB;


/**
 * A virtual program graph for use in an Eclipse environment.
 * <a href="../../../../overview-summary.html#Eclipse">More Information</a>
 * <p>
 * This class is intended to be subclassed directly.
 *
 * @author Jeff Overbey
 */
public abstract class EclipseVPG<A, T, R extends TokenRef<T>, D extends VPGDB<A, T, R, L>, L extends EclipseVPGLog<T, R>>
              extends VPG<A, T, R, D, L>
{
    private String syncMessage;

    public EclipseVPG(L log, D database, String syncMessage, int transientASTCacheSize)
    {
        super(log, database, transientASTCacheSize);
        this.syncMessage = syncMessage;
    }

    public EclipseVPG(L log, D database, String syncMessage)
    {
        super(log, database);
        this.syncMessage = syncMessage;
    }

    /** Enqueues a job to make sure the VPG is up-to-date with the
     *  workspace, and instructs it to automatically update itself
     *  when files are added, changed, or deleted in the workspace.
     */
    public void start()
    {
        log.readLogFromFile();
        
        // Now listen for changes to workspace resources
        ResourcesPlugin.getWorkspace().addResourceChangeListener(new VPGResourceChangeListener(), IResourceChangeEvent.POST_CHANGE);

        // The C/C++ Development Tool (see org.eclipse.cdt.internal.core.model.CModelManager) handles
        // IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.PRE_DELETE | IResourceChangeEvent.PRE_CLOSE

        // and also executes
        // Platform.getContentTypeManager().addContentTypeChangeListener(this);

        queueJobToEnsureVPGIsUpToDate();
    }

    ///////////////////////////////////////////////////////////////////////////
    // Resource Visitor
    ///////////////////////////////////////////////////////////////////////////

    public WorkspaceJob queueJobToEnsureVPGIsUpToDate()
    {
        WorkspaceJob job = new VPGInitialWorkspaceSyncJob(syncMessage);
        job.setRule(MultiRule.combine(VPGSchedulingRule.getInstance(),
                    ResourcesPlugin.getWorkspace().getRoot()));
        job.schedule();
        return job;
    }

    private final class VPGInitialWorkspaceSyncJob extends VPGJob<A, T>
    {
        private VPGInitialWorkspaceSyncJob(String name)
        {
            super(name);
        }

        @Override public IStatus runInWorkspace(final IProgressMonitor monitor)
        {
            try
            {
                monitor.beginTask("Indexing", IProgressMonitor.UNKNOWN);
                return ensureVPGIsUpToDate(monitor);
            }
            finally
            {
                monitor.done();
            }
        }
    }

    /** Ensures that the VPG database contains up-to-date information for all of
     *  the resources in the workspace.
     */
    public IStatus ensureVPGIsUpToDate(IProgressMonitor monitor)
    {
        try
        {
            WorkspaceSyncResourceVisitor visitor = new WorkspaceSyncResourceVisitor();
            collectFilesToIndex(visitor, monitor);
            visitor.calculateDependencies(monitor);
            visitor.index(monitor);
            return Status.OK_STATUS;
        }
        catch (CoreException e)
        {
            return e.getStatus();
        }
    }

    private void collectFilesToIndex(WorkspaceSyncResourceVisitor visitor, IProgressMonitor monitor) throws CoreException
    {
        monitor.subTask("Searching for workspace modifications...");
        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
        workspaceRoot.accept(visitor); // Collect list of files to index
    }

    private final class WorkspaceSyncResourceVisitor implements IResourceVisitor
    {
        private final ArrayList<String> files;

        private WorkspaceSyncResourceVisitor()
        {
            this.files = new ArrayList<String>(1024);
        }

        public boolean visit(IResource resource)
        {
            try
            {
                if (!resource.isAccessible()) return false;

                if (resource instanceof IProject && !shouldProcessProject((IProject)resource)) return false;

                if (resource instanceof IFile && shouldProcessFile((IFile)resource))
                    files.add(EclipseVPG.getFilenameForIFile((IFile)resource));
            }
            catch (Exception e)
            {
                log.logError(e);
            }
            return !(resource instanceof IFile);
        }

        public void calculateDependencies(IProgressMonitor monitor)
        {
            ArrayList<String> queue = files;
            int completed = 0, total = queue.size();
            for (String filename : queue)
            {
                if (monitor.isCanceled()) throw new OperationCanceledException();

                monitor.subTask(filename + " (calculating dependencies - file " + (++completed) + " of " + total + ")");
                calculateDependenciesIfNotUpToDate(filename);
            }
        }

        public void index(IProgressMonitor monitor)
        {
            List<String> queue = sortFilesAccordingToDependencies(files, monitor);

            int completed = 0, total = countFilesInQueue(queue);
            for (String filename : queue)
            {
                if (monitor.isCanceled()) throw new OperationCanceledException();

                if (shouldListFileInIndexerProgressMessages(filename))
                    monitor.subTask(filename + " (" + (++completed) + " of " + total + ")");

                indexIfNotUpToDate(filename);
            }
        }
    }

    private int countFilesInQueue(List<String> queue)
    {
        int total = 0;
        for (String filename : queue)
            if (shouldListFileInIndexerProgressMessages(filename))
                total++;
        return total;
    }

    protected boolean shouldListFileInIndexerProgressMessages(String filename) {
        return !isVirtualFile(filename);
    }

    //public ArrayList<String> sortFilesAccordingToDependencies(final ArrayList<String> files, final IProgressMonitor monitor)

    ///////////////////////////////////////////////////////////////////////////
    // Resource Change Listener
    ///////////////////////////////////////////////////////////////////////////

    private final class VPGResourceChangeListener implements IResourceChangeListener
    {
        public void resourceChanged(IResourceChangeEvent event)
        {
            if (!(event.getSource() instanceof IWorkspace)) return;

            if (event.getType() != IResourceChangeEvent.POST_CHANGE) return;

            final IResourceDelta delta = event.getDelta();
            if (delta == null) return;

            new VPGResourceDeltaJob(syncMessage, delta).schedule();
        }
    }

    private final class VPGResourceDeltaJob extends VPGJob<A, T>
    {
        private final IResourceDelta delta;

        private VPGResourceDeltaJob(String name, IResourceDelta delta)
        {
            super(name);
            this.delta = delta;
        }

        @Override public IStatus runInWorkspace(final IProgressMonitor monitor)
        {
            try
            {
                monitor.beginTask("Indexing", IProgressMonitor.UNKNOWN);
                // Re-index or delete entries for files when they are added/changed or deleted, respectively
                VPGResourceDeltaVisitor visitor = new VPGResourceDeltaVisitor();
                monitor.subTask("Searching for workspace modifications...");
                delta.accept(visitor); // Collect files to index
                visitor.calculateDependencies(monitor);
                visitor.index(monitor);
                return Status.OK_STATUS;
            }
            catch (CoreException e)
            {
                return e.getStatus();
            }
            finally
            {
                monitor.done();
            }
        }
    }

    private final class VPGResourceDeltaVisitor implements IResourceDeltaVisitor
    {
        private ArrayList<String> files;
        private HashMap<String, Boolean> forceReindex;

        public VPGResourceDeltaVisitor()
        {
            this.files = new ArrayList<String>(256);
            this.forceReindex = new HashMap<String, Boolean>(256);
        }

        public boolean visit(IResourceDelta delta)
        {
            try
            {
                IResource resource = delta.getResource();
                if (!(resource instanceof IFile))
                {
                    if (resource instanceof IProject)
                        return shouldProcessProject((IProject)resource);
                    else
                        return true;
                }
                IFile file = (IFile)resource;
                if (!shouldProcessFile(file)) return true;

                String filename = getFilenameForIFile(file);

                switch (delta.getKind())
                {
                case IResourceDelta.ADDED:
                    debug("Resource Delta: Add", filename);
                    files.add(filename);
                    forceReindex.put(filename, true); // Was false
                    break;

                case IResourceDelta.CHANGED:
                    debug("Resource Delta: Change", filename);
                    if ((delta.getFlags() & (IResourceDelta.CONTENT|IResourceDelta.REPLACED)) != 0)
                    {
                        files.add(filename);
                        forceReindex.put(filename, true);
                    }
                    break;

                case IResourceDelta.REMOVED:
                    debug("Resource Delta: Remove", filename);
                    log.clearEntriesFor(filename);
                    db.deleteAllEntriesFor(filename);
                    break;
                }
            }
            catch (Exception e)
            {
                log.logError(e);
            }
            return true;
        }

        public void calculateDependencies(IProgressMonitor monitor)
        {
            ArrayList<String> queue = files;
            int completed = 0, total = queue.size();
            for (String filename : queue)
            {
                if (monitor.isCanceled()) throw new OperationCanceledException();

                monitor.subTask(filename + " (" + (++completed) + " of " + total + ")");
                Boolean force = forceReindex.get(filename);
                if (force == null || force)
                    forceRecomputationOfDependencies(filename);
                else
                    calculateDependenciesIfNotUpToDate(filename);
            }
        }

        public void index(IProgressMonitor monitor)
        {
            List<String> queue = sortFilesAccordingToDependencies(files, monitor);
            int completed = 0, total = countFilesInQueue(queue);
            for (String filename : queue)
            {
                if (monitor.isCanceled()) throw new OperationCanceledException();

                if (shouldListFileInIndexerProgressMessages(filename))
                    monitor.subTask(filename + " (" + (++completed) + " of " + total + ")");

                Boolean force = forceReindex.get(filename);
                if (force == null || force)
                    forceRecomputationOfEdgesAndAnnotations(filename);
                else
                    indexIfNotUpToDate(filename);
            }
        }
    }

    /** Updates the VPG database's dependency information for the given file
     *  if the stored information is out of date
     * @param monitor */
    protected void calculateDependenciesIfNotUpToDate(String filename)
    {
        if (db.isOutOfDate(filename))
        {
            debug("Indexing", filename);
            forceRecomputationOfDependencies(filename);
        }
        else
        {
            debug("Index is up to date", filename);
        }
    }

    /** Updates the VPG database information for the given file if the stored
     *  information is out of date
     * @param monitor */
    protected void indexIfNotUpToDate(String filename)
    {
        if (db.isOutOfDate(filename))
        {
            debug("Indexing", filename);
            forceRecomputationOfEdgesAndAnnotations(filename);
        }
        else
        {
            debug("Index is up to date", filename);
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    // Abstract Methods (Resource Filtering)
    ///////////////////////////////////////////////////////////////////////////

    /** @return true iff the given file should be parsed */
    @Override protected boolean shouldProcessFile(String filename)
    {
        IFile file = getIFileForFilename(filename);
        return file == null ? false : shouldProcessFile(file);
    }

    /** @return true if the given project should be indexed */
    protected abstract boolean shouldProcessProject(IProject project);

    /** @return true iff the given file should be indexed */
    protected abstract boolean shouldProcessFile(IFile file);

    ///////////////////////////////////////////////////////////////////////////
    // Utility Methods (IFile<->Filename Mapping)
    ///////////////////////////////////////////////////////////////////////////

    public static IFile getIFileForFilename(String filename)
    {
        IResource resource = getIResourceForFilename(filename);
        if (resource instanceof IFile)
            return (IFile)resource;
        else
            return null;
    }

    public static String getFilenameForIFile(IFile file)
    {
        return getFilenameForIResource(file);
    }

    public static IResource getIResourceForFilename(String filename)
    {
        return ResourcesPlugin.getWorkspace().getRoot().findMember(filename);
    }

    public static String getFilenameForIResource(IResource resource)
    {
        if (resource == null)
            return null;
        else
            return resource.getFullPath().toString();
    }

    ///////////////////////////////////////////////////////////////////////////
    // IFile-Based AST Acquisition & Release API
    ///////////////////////////////////////////////////////////////////////////

    public A acquireTransientAST(IFile file)
    {
        return file == null ? null : acquireTransientAST(getFilenameForIFile(file));
    }

    public A acquirePermanentAST(IFile file)
    {
        return file == null ? null : acquirePermanentAST(getFilenameForIFile(file));
    }
    
    public A makeTransientASTPermanent(IFile file)
    {
        return file == null ? null : makeTransientASTPermanent(getFilenameForIFile(file));
    }

    public A makeTransientASTPermanent(IFile file, A ast)
    {
        return file == null ? null : makeTransientASTPermanent(getFilenameForIFile(file), ast);
    }

    public void releaseAST(IFile file)
    {
        if (file != null) releaseAST(getFilenameForIFile(file));
    }
    
    public IFile getIFileCorrespondingTo(A ast)
    {
        String filename = getFilenameCorrespondingTo(ast);
        return filename == null ? null : getIFileForFilename(filename);
    }

    ///////////////////////////////////////////////////////////////////////////
    // VPG Overrides
    ///////////////////////////////////////////////////////////////////////////

    @Override protected void processingDependent(String filename, String dependentFilename)
    {
//        if (progressMonitor != null)
//            progressMonitor.subTask(filename
//                                    + " - reindexing dependent file "
//                                    + dependentFilename);
        super.processingDependent(filename, dependentFilename);
    }

    /** Forces the database to be updated based on the current in-memory AST for the given file */
    public void commitChangesFromInMemoryASTs(IProgressMonitor pm, int ticks, IFile file)
    {
        commitChangesFromInMemoryASTs(pm, ticks, getFilenameForIFile(file));
    }

    /** Forces the database to be updated based on the current in-memory ASTs for the given files */
    public void commitChangesFromInMemoryASTs(IProgressMonitor pm, int ticks, Set<IFile> files)
    {
        String[] filenames = new String[files.size()];
        int i = 0;
        for (IFile file : files)
            filenames[i++] = getFilenameForIFile(file);
        
        commitChangesFromInMemoryASTs(pm, ticks, filenames);
    }
}
