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

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

				public Collection getChangedResources() {
					return changedResources;
				}

				public Collection getRemovedResources() {
					return removedResources;
				}

			}
			;

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

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

}