//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation 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:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.persistence.refresh;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

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.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.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.epf.persistence.FileManager;
import org.eclipse.epf.persistence.MultiFileResourceSetImpl;
import org.eclipse.epf.persistence.MultiFileSaveUtil;
import org.eclipse.epf.persistence.MultiFileXMIResourceImpl;
import org.eclipse.epf.persistence.PersistencePlugin;
import org.eclipse.epf.persistence.util.LibrarySchedulingRule;
import org.eclipse.epf.persistence.util.PersistenceResources;
import org.eclipse.epf.persistence.util.PersistenceUtil;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;

/**
 * Background job that keeps notifying refresh handlers about changes in
 * resources
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class RefreshJob extends WorkspaceJob implements IResourceChangeListener {

	private static final long UPDATE_DELAY = 200;

	private static final boolean DEBUG = PersistencePlugin.getDefault().isDebugging();

	private static final String DEBUG_PREFIX = "EPF Auto-refresh:"; //$NON-NLS-1$

	private ResourceSet resourceSet;

	private Collection<Resource> addedResources = new UniqueEList<Resource>();

	private Collection<Resource> changedResources = new UniqueEList<Resource>();

	private Collection<Resource> removedResources = new UniqueEList<Resource>();
	
	private Collection<Resource> movedResources = new UniqueEList<Resource>();

	private UniqueEList<Resource> savedResources = new UniqueEList<Resource>();

	private Collection<Resource> loadedBeforeRefreshResources = new ArrayList<Resource>();

	private IRefreshHandler refreshHandler;

	private boolean enabled = true;

	private Collection<IResource> addedWorkspaceResources = new UniqueEList<IResource>();

	private RefreshJob() {
		super(PersistenceResources.resourceAutoRefreshJob_name);
	}

	public void setEnabled(boolean b) {
		enabled = b;
	}

	public boolean isEnabled() {
		return enabled;
	}

	/**
	 * @param resourceSet
	 *            The resourceSet to set.
	 */
	public void setResourceSet(ResourceSet resourceSet) {
		this.resourceSet = resourceSet;
	}
	
	public ResourceSet getResourceSet() {
		return resourceSet;
	}

	public void setRefreshHandler(IRefreshHandler handler) {
		refreshHandler = handler;
	}

	/**
	 * Gets existing resources that reappear in workspaces
	 * 
	 * @return the addedResources
	 */
	public Collection<Resource> getAddedResources() {
		removeResources(addedResources, savedResources);
		return addedResources;
	}

	public Collection<IResource> getAddedWorkspaceResources() {
		return addedWorkspaceResources;
	}

	/**
	 * @return Returns the changedResources.
	 */
	public Collection<Resource> getChangedResources() {
		removeResources(changedResources, savedResources);
		removeResources(changedResources, loadedBeforeRefreshResources);
		return changedResources;
	}

	/**
	 * Removes <code>resourcesToRemove</code> from <code>resources</code> if
	 * the resources are synchronized with their storage.
	 * 
	 * @param resourcesToRemove
	 */
	private static void removeResources(Collection<Resource> resources,
			Collection<Resource> resourcesToRemove) {
		synchronized (resourcesToRemove) {
			if (!resourcesToRemove.isEmpty()) {
				for (Iterator<Resource> iter = resourcesToRemove.iterator(); iter
						.hasNext();) {
					Object resource = iter.next();
					boolean canRemove = true;
					if (resource instanceof MultiFileXMIResourceImpl) {
						MultiFileXMIResourceImpl mfResource = ((MultiFileXMIResourceImpl) resource);
						canRemove = mfResource.isSynchronized();
					}
					if (canRemove) {
						if (resources.remove(resource)) {
							iter.remove();
						}
					}
				}
			}
		}
	}

	/**
	 * @return Returns the removedResources.
	 */
	public Collection<Resource> getRemovedResources() {
		return removedResources;
	}
	
	/**                                    
	 * @return Returns the movedResources. 
	 */                                    
	public Collection<Resource> getMovedResources() {
		return movedResources;             
	}                                      

	public void resourceSaved(Resource resource) {
		if(resource.getResourceSet() == resourceSet) {
			synchronized (savedResources) {
				savedResources.add(resource);
			}
		}
	}

	/**
	 * @return the loadedBeforeRefreshResources
	 */
	public Collection<Resource> getReloadedBeforeRefreshResources() {
		return loadedBeforeRefreshResources;
	}

	public void reset() {
		changedResources.clear();
		removedResources.clear();
		movedResources.clear();
		savedResources.clear();
		loadedBeforeRefreshResources.clear();
		addedResources.clear();
		addedWorkspaceResources.clear();
	}
	
	private MethodLibrary getMethodLibrary() {
		if(resourceSet instanceof MultiFileResourceSetImpl) {
			return ((MultiFileResourceSetImpl)resourceSet).getMethodLibrary();
		}
		return null;
	}

	private void scheduleRefresh() {		
		if (getState() == Job.NONE) {
			MethodLibrary lib = getMethodLibrary();
			if(lib != null) {
				setRule(new LibrarySchedulingRule(lib));
				schedule(UPDATE_DELAY);
			}
		}
	}	

	/*
	 * (non-Javadoc)
	 * 
	 * @see WorkspaceJob#runInWorkspace
	 */
	public IStatus runInWorkspace(IProgressMonitor monitor) {
		if (refreshHandler == null)
			return Status.OK_STATUS;

		// wait for all workspace refresh jobs to finish first
		//
		try {
			getJobManager().join(ResourcesPlugin.FAMILY_AUTO_REFRESH, new NullProgressMonitor());
		} catch (OperationCanceledException e1) {
		} catch (InterruptedException e1) {
		}
		
		long start = System.currentTimeMillis();
		Throwable error = null;
		try {
			if (DEBUG)
				System.out.println(DEBUG_PREFIX + " starting refresh job"); //$NON-NLS-1$
			monitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$
			if (monitor.isCanceled())
				throw new OperationCanceledException();
			try {
				refreshHandler.refresh(monitor);
			} catch (Throwable e) {
				error = e;
			}
		} finally {
			monitor.done();
			if (DEBUG)
				System.out
						.println(DEBUG_PREFIX
								+ " finished refresh job in: " + (System.currentTimeMillis() - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		if (error != null)
			return new Status(IStatus.ERROR, FileManager.PLUGIN_ID, 0,
					"Refresh error", error); //$NON-NLS-1$
		return Status.OK_STATUS;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.runtime.jobs.Job#shouldRun()
	 */
	public synchronized boolean shouldRun() {
		return shouldRefresh();
	}

	private boolean shouldRefresh() {
		return !removedResources.isEmpty() || !changedResources.isEmpty()
				|| !addedResources.isEmpty() || !movedResources.isEmpty()
				|| !loadedBeforeRefreshResources.isEmpty()
				|| !addedWorkspaceResources.isEmpty();
	}

	/**
	 * Starts the refresh job
	 */
	public void start() {
		if (DEBUG) {
			System.out.println("RefreshJob.start()"); //$NON-NLS-1$
		}
		ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
	}

	/**
	 * Stops the refresh job
	 */
	public void stop() {
		if (DEBUG) {
			System.out.println("RefreshJob.stop()"); //$NON-NLS-1$
		}
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
		cancel();
	}

	public Resource getResource(IResource wsRes) {
		if(resourceSet instanceof MultiFileResourceSetImpl) {
			return ((MultiFileResourceSetImpl)resourceSet).getResource(wsRes);
		}
		IPath path = wsRes.getLocation();
		return path != null ? PersistenceUtil.getResource(path, resourceSet) : null;
	}

	/**
	 * Checks if the given resource can be accepted as a new resource of
	 * resource set of this refresh job that needs to be loaded.
	 * 
	 * @param resource
	 * @return
	 */
	private boolean accept(IResource resource) {
		if (resourceSet instanceof MultiFileResourceSetImpl) {
			return ((MultiFileResourceSetImpl) resourceSet)
					.isNewResourceToLoad(resource);
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
	 */
	public void resourceChanged(IResourceChangeEvent event) {
		if (!isEnabled() || resourceSet == null)
			return;
		IResourceDelta delta = event.getDelta();
		if (delta == null)
			return;		
		try {
			class ResourceDeltaVisitor implements IResourceDeltaVisitor {
				private Collection<Resource> changedResources = new ArrayList<Resource>();

				private Collection<Resource> removedResources = new ArrayList<Resource>();
				
				private Collection<Resource> movedResources = new ArrayList<Resource>();

				private Collection<Resource> addedResources = new ArrayList<Resource>();

				private ArrayList<IResource> addedWorkspaceResources = new ArrayList<IResource>();
				
				public boolean visit(IResourceDelta delta) throws CoreException {
					Resource resource;
//					System.out.println("type=" + delta.getResource().getType());
//					System.out.println("kind=" + delta.getKind());
//					System.out.println(delta.getFlags() != IResourceDelta.MARKERS);
//					if(delta.getResource().getFullPath().toString().endsWith("plugin.xmi")) {
//						System.out.println(delta.getResource().getFullPath().toString());
//					}
					if (delta.getResource().getType() == IResource.FILE) {
						switch (delta.getKind()) {
						case IResourceDelta.ADDED:
							// handle added resource
							//
							resource = getResource(delta.getResource());
							if (resource != null) {
								if (!resource.isLoaded()) {
									// the resource was created but not
									// loaded b/c the workspace resource
									// was not added to the workspace at the
									// time of loading
									//
									MethodElement me = PersistenceUtil
									.getMethodElement(resource);
									if (!(me instanceof ContentDescription)) {
										// no auto-reload for content
										// description
										// MethodElementEditor will detect
										// the change and load it
										// when activated.
										//
										addedResources.add(resource);
									}
								}
							} else if (accept(delta.getResource())) {
								addedWorkspaceResources.add(delta
										.getResource());
							}
							
							// handle file move
							//
							if ((IResourceDelta.MOVED_FROM & delta.getFlags()) != 0) {
//								resource = getResource(delta.getResource());          
//								if (resource != null) {                           
//									movedResources.add(resource);                 
//								}                                                 
								//
								if (DEBUG) {
									IPath movedFromPath = delta.getResource()
											.getLocation();
									IPath movedToPath = delta.getMovedToPath();
									System.out
											.println("Resource moved from '" + movedFromPath + "' to '" + movedToPath + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
								}

							}
							break;
						case IResourceDelta.REMOVED:
							resource = getResource(delta.getResource());
							if (resource != null) {
								removedResources.add(resource);
							}
							break;
						case IResourceDelta.CHANGED:
							boolean encodingChanged = ((IResourceDelta.ENCODING & delta
									.getFlags()) != 0);
							boolean contentChanged = ((IResourceDelta.CONTENT & delta
									.getFlags()) != 0);
							if (encodingChanged || contentChanged) {
								resource = getResource(delta.getResource());
								if (resource != null
										&& MultiFileSaveUtil
										.checkSynchronized(resource) != 1) {
									changedResources.add(resource);
								}
							}
							break;
						}
					}
					
					return true;
				}

			};                                             

			ResourceDeltaVisitor visitor = new ResourceDeltaVisitor();
			delta.accept(visitor);

			removedResources.addAll(visitor.removedResources);
			movedResources.addAll(visitor.movedResources);
			changedResources.addAll(visitor.changedResources);
			addedResources.addAll(visitor.addedResources);
			addedWorkspaceResources.addAll(visitor.addedWorkspaceResources);

			if (shouldRefresh()) {
				scheduleRefresh();
			}
		} catch (CoreException e) {
			CommonPlugin.INSTANCE.log(e);
		}
	}

	/**
	 * Resolves the proxy and its containers
	 * 
	 * @param proxy
	 * @return
	 */
	public EObject resolve(EObject proxy) {
		return PersistenceUtil.resolve(proxy, resourceSet);
	}

	public static RefreshJob getInstance() {
		return instance;
	}

	private static RefreshJob instance = new RefreshJob();

}