//------------------------------------------------------------------------------
// 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 java.util.List;

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.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
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();
	}

	//TODO: move this method to a utility class and make it static
	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;
	}

	//TODO: move this method to a utility class and make it static
	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
	 * 
	 * TODO: move this method to a utility class and make it static
	 * 
	 * @param proxy
	 * @return
	 */
	public EObject resolve(EObject proxy) {
		EObject resolved;
		try {
			resolved = EcoreUtil.resolve(proxy, resourceSet);
		} catch (Exception e) {
			resolved = proxy;
		}
		EObject container = proxy.eContainer();
		if (resolved.eContainer() == null && container != null) {
			if (container.eIsProxy()) {
				container = resolve(container);
			}
			EReference ref = proxy.eContainmentFeature();
			if (ref.isMany()) {
				List values = (List) container.eGet(ref);
				for (Iterator iter = values.iterator(); iter.hasNext(); iter
						.next())
					;
			} else {
				container.eGet(ref);
			}
		}
		return resolved;
	}

	public static RefreshJob getInstance() {
		return instance;
	}

	private static RefreshJob instance = new RefreshJob();

}