//------------------------------------------------------------------------------
// 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();
	}

	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
	 * 
	 * 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();

}