//------------------------------------------------------------------------------
// 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.io.File;
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.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.URI;
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.PersistenceUtil;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.MethodElement;

/**
 * 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 addedResources = new UniqueEList();

	private Collection changedResources = new UniqueEList();

	private Collection removedResources = new UniqueEList();
	
	private Collection movedResources = new UniqueEList();

	private UniqueEList savedResources = new UniqueEList();

	private Collection loadedBeforeRefreshResources = new ArrayList();

	private IRefreshHandler refreshHandler;

	private boolean enabled = true;

	private Collection addedWorkspaceResources = new UniqueEList();

	private RefreshJob() {
		super("EPF Auto-Refresh"); //$NON-NLS-1$
	}

	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 void setRefreshHandler(IRefreshHandler handler) {
		refreshHandler = handler;
	}

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

	public Collection getAddedWorkspaceResources() {
		return addedWorkspaceResources;
	}

	/**
	 * @return Returns the changedResources.
	 */
	public Collection 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 resources,
			Collection resourcesToRemove) {
		synchronized (resourcesToRemove) {
			if (!resourcesToRemove.isEmpty()) {
				for (Iterator iter = resourcesToRemove.iterator(); iter
						.hasNext();) {
					Object resource = iter.next();
					boolean canRemove = true;
					if (resource instanceof MultiFileXMIResourceImpl) {
						MultiFileXMIResourceImpl mfResource = ((MultiFileXMIResourceImpl) resource);
						long currentTime = new File(mfResource.getURI()
								.toFileString()).lastModified();
						canRemove = currentTime == mfResource
								.getFileLastModified()
								|| MultiFileSaveUtil.same(currentTime,
										mfResource.getFileLastModified());
					}
					if (canRemove) {
						if (resources.remove(resource)) {
							iter.remove();
						}
					}
				}
			}
		}
	}

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

	public void resourceSaved(Resource resource) {
		synchronized (savedResources) {
			savedResources.add(resource);
		}
	}

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

	public void reset() {
		changedResources.clear();
		removedResources.clear();
		movedResources.clear();
		savedResources.clear();
		loadedBeforeRefreshResources.clear();
		addedResources.clear();
		addedWorkspaceResources.clear();
	}

	private void scheduleRefresh() {
		if (getState() == Job.NONE) {
			schedule(UPDATE_DELAY);
		}
	}

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

		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(String path) {
		URI uri = URI.createFileURI(path);
		for (Iterator iter = new ArrayList(resourceSet.getResources())
				.iterator(); iter.hasNext();) {
			Resource resource = (Resource) iter.next();
			if (uri.equals(resource.getURI())) {
				return resource;
			}
		}
		return null;
	}

	public Resource getResource(IResource wsRes) {
		return getResource(wsRes.getLocation().toString());
	}

	/**
	 * 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 changedResources = new ArrayList();

				private Collection removedResources = new ArrayList();
				
				private Collection movedResources = new ArrayList();

				private Collection addedResources = new ArrayList();

				private ArrayList addedWorkspaceResources = new ArrayList();

				public boolean visit(IResourceDelta delta) throws CoreException {
					Resource resource;
					IPath path;
					String loc;
					if (delta.getFlags() != IResourceDelta.MARKERS
							&& delta.getResource().getType() == IResource.FILE) {
						switch (delta.getKind()) {
						case IResourceDelta.ADDED:
							// handle added resource
							//
							path = delta.getResource().getLocation();
							if (path != null) {
								loc = path.toString();
								resource = getResource(loc);
								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());
								}
							}
							break;
						case IResourceDelta.REMOVED:
							if ((IResourceDelta.MOVED_TO & delta.getFlags()) != 0) {
								// handle file move
								path = delta.getResource().getLocation();             
								if(path != null) {                                    
									resource = getResource(path.toString());          
									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$
								}

							} else {
								path = delta.getResource().getLocation();
								if (path != null) {
									resource = getResource(path.toString());
									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) {
								path = delta.getResource().getLocation();
								if (path != null) {
									loc = path.toString();
									resource = getResource(loc);
									if (resource != null
											&& MultiFileSaveUtil
													.checkSynchronized(resource) != 1) {
										changedResources.add(resource);
									}
								}
							}
							break;
						}
					}
					// watch for project move                                                         
					else if (delta.getFlags() != IResourceDelta.MARKERS                               
							&& delta.getResource().getType() == IResource.PROJECT) {                  
						// tested using the Move.. command in the Resource Navigator view             
						// the REPLACED flag only seemed to occur when the library was moved          
						// outside of EPF and EPF was re-started, so make sure it's clear, otherwise  
						// we reload the library right after loading it when starting EPF             
						if (delta.getKind() == IResourceDelta.CHANGED &&                              
								((delta.getFlags() & IResourceDelta.REPLACED) == 0) &&                
								((delta.getFlags() & IResourceDelta.DESCRIPTION) != 0)) {             
							movedResources.add(delta.getResource());                                  
									                                                                  
						}                                                                             
						return true;                                                                  
					}                                                                                 
					return true;
				}

				public Collection getChangedResources() {
					return changedResources;
				}

				public Collection getRemovedResources() {
					return removedResources;
				}

				public Collection getMovedResources() {    
					return movedResources;                 
				}                                          
			};                                             

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

			removedResources.addAll(visitor.getRemovedResources());
			movedResources.addAll(visitor.getMovedResources());
			changedResources.addAll(visitor.getChangedResources());
			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();

}