/*******************************************************************************
 * Copyright (c) 2003, 2005 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 API and implementation
 *******************************************************************************/
package org.eclipse.wst.common.internal.emfworkbench.validateedit;


import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jem.util.emf.workbench.WorkbenchResourceHelperBase;
import org.eclipse.wst.common.internal.emf.resource.ReferencedResource;
import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;

public class ResourceStateValidatorImpl implements ResourceStateValidator {
	protected ResourceStateInputProvider provider;
	protected Map lastNonRefreshStateMap;
	protected boolean isCheckingConsistency;

	class RefreshRunnable implements IWorkspaceRunnable {
		CoreException thrownException;
		List files;
		List resources;

		RefreshRunnable(List someFiles, List inconsistentResources) {
			files = someFiles;
			resources = inconsistentResources;
		}

		public CoreException getThrownException() {
			return thrownException;
		}

		public void run(IProgressMonitor aMonitor) {
			try {
				prepareResourcesForRefresh(resources);
				primRefreshFiles(files);
			} catch (CoreException e) {
				thrownException = e;
			}
		}
	}

	/**
	 * Constructor for ResourceStateValidator.
	 */
	public ResourceStateValidatorImpl(ResourceStateInputProvider aProvider) {
		provider = aProvider;
	}

	/**
	 * This method should be called whenever <code>aListener</code> is activated (becomes active).
	 * This will check the timestamps of the underlying files to see if they are different from the
	 * last cached modified value. <code>aListener</code> should be prepared to prompt the user if
	 * they would like to refresh with the contents on disk if we are dirty.
	 */
	public void checkActivation(ResourceStateValidatorPresenter presenter) throws CoreException {
		checkConsistency(presenter);
	}

	public void lostActivation(ResourceStateValidatorPresenter presenter) throws CoreException {
		checkConsistency(presenter);
	}

	public boolean checkSave(ResourceStateValidatorPresenter presenter) throws CoreException {
		if (presenter == null)
			return false;
		if (!provider.isDirty())
			return false;
		List inconsistentResources = getInconsistentResources();
		List inconsistentFiles = getFiles(inconsistentResources);
		inconsistentFiles = addOtherInconsistentFiles(inconsistentFiles);
		if (inconsistentFiles == null || inconsistentFiles.isEmpty())
			return true;
		return presenter.promptForInconsistentFileOverwrite(inconsistentFiles);
	}

	/**
	 * @see ResourceStateValidator#checkReadOnly()
	 */
	public boolean checkReadOnly() {
		boolean result = checkReadOnlyResources();
		if (!result)
			result = checkReadOnlyNonResourceFiles();
		return result;
	}

	/**
	 * Method checkReadOnlyNonResourceFiles.
	 * 
	 * @return boolean
	 */
	private boolean checkReadOnlyNonResourceFiles() {
		List files = provider.getNonResourceFiles();
		if (files == null || files.isEmpty())
			return false;
		int size = files.size();
		IFile file = null;
		for (int i = 0; i < size; i++) {
			file = (IFile) files.get(i);
			if (file.isReadOnly())
				return true;
		}
		return false;
	}

	/**
	 * Method checkReadOnlyResources.
	 * 
	 * @return boolean
	 */
	private boolean checkReadOnlyResources() {
		List resources = provider.getResources();
		if (resources == null || resources.isEmpty())
			return false;
		int size = resources.size();
		Resource res = null;
		IFile file = null;
		for (int i = 0; i < size; i++) {
			res = (Resource) resources.get(i);
			file = WorkbenchResourceHelper.getFile(res);
			if (file != null && file.isReadOnly())
				return true;
		}
		return false;
	}

	protected void checkConsistency(ResourceStateValidatorPresenter presenter) throws CoreException {
		if (isCheckingConsistency || presenter == null)
			return;
		isCheckingConsistency = true;
		try {
			List inconsistentResources = getInconsistentResources();
			List inconsistentFiles = getFiles(inconsistentResources);
			inconsistentFiles = addOtherInconsistentFiles(inconsistentFiles);
			if (inconsistentFiles == null || inconsistentFiles.isEmpty())
				return;
			boolean shouldRefreshFiles = true;
			//Defect 208654 & 209631 want prompt no matter what.
			if (anyFileChangedSinceLastRefreshPrompt(inconsistentFiles)) {
				clearLastNonRefreshStateMap();
				shouldRefreshFiles = presenter.promptForInconsistentFileRefresh(inconsistentFiles);
			} else
				return;
			if (shouldRefreshFiles)
				refreshFiles(inconsistentFiles, inconsistentResources);
			else
				cacheLastNonRefreshFileStamps(inconsistentFiles);
		} finally {
			isCheckingConsistency = false;
		}
	}

	/**
	 * Method cacheLastNonRefreshFileStamps.
	 * 
	 * @param inconsistentFiles
	 */
	private void cacheLastNonRefreshFileStamps(List inconsistentFiles) {
		if (inconsistentFiles != null && !inconsistentFiles.isEmpty()) {
			Map map = getLastNonRefreshStateMap();
			IFile file = null;
			long stamp = 0;
			for (int i = 0; i < inconsistentFiles.size(); i++) {
				file = (IFile) inconsistentFiles.get(i);
				stamp = WorkbenchResourceHelper.computeModificationStamp(file);
				map.put(file, new Long(stamp));
			}
		}
	}

	/**
	 * Method cacheValidateState.
	 * 
	 * @param result
	 */
	private void cacheValidateState(IStatus aStatus, List readOnlyResources, List roNonResourceFiles) {
		if (aStatus.isOK()) {
			if (readOnlyResources != null && !readOnlyResources.isEmpty()) {
				ReferencedResource res = null;
				for (int i = 0; i < readOnlyResources.size(); i++) {
					res = (ReferencedResource) readOnlyResources.get(i);
					WorkbenchResourceHelper.setSynhronizationStamp(res, computeModificationStamp(res));
				}
			}
			provider.cacheNonResourceValidateState(roNonResourceFiles);
		}
	}

	private void clearLastNonRefreshStateMap() {
		if (lastNonRefreshStateMap != null)
			lastNonRefreshStateMap.clear();
	}

	/**
	 * Method anyFileChangedSinceLastRefreshPrompt.
	 * 
	 * @param inconsistentFiles
	 * @return boolean
	 */
	private boolean anyFileChangedSinceLastRefreshPrompt(List inconsistentFiles) {
		if (inconsistentFiles == null || inconsistentFiles.isEmpty())
			return false;
		if (lastNonRefreshStateMap == null || lastNonRefreshStateMap.isEmpty())
			return true;
		int size = inconsistentFiles.size();
		IFile file = null;
		Long stamp = null;
		for (int i = 0; i < size; i++) {
			file = (IFile) inconsistentFiles.get(i);
			stamp = (Long) getLastNonRefreshStateMap().get(file);
			if (stamp == null || (stamp.longValue() != WorkbenchResourceHelper.computeModificationStamp(file)))
				return true;
		}
		return false;
	}

	protected List addOtherInconsistentFiles(List inconsistentFiles) {
		if (inconsistentFiles == null || inconsistentFiles.isEmpty())
			return getNonResourceInconsistentFiles();
		List nonResFiles = getNonResourceInconsistentFiles();
		if (nonResFiles != null)
			inconsistentFiles.addAll(nonResFiles);
		return inconsistentFiles;
	}

	/**
	 * Method getNonResourceInconsistentFiles.
	 * 
	 * @return List
	 */
	private List getNonResourceInconsistentFiles() {
		List files = provider.getNonResourceInconsistentFiles();
		if (files != null && !files.isEmpty())
			return files;
		//Determine consistency based on the synchronization of the IFile
		files = provider.getNonResourceFiles();
		if (files == null || files.isEmpty())
			return Collections.EMPTY_LIST;
		List inconsistent = null;
		int size = files.size();
		IFile file = null;
		for (int i = 0; i < size; i++) {
			file = (IFile) files.get(i);
			if (file.isAccessible() && !file.isSynchronized(IResource.DEPTH_ZERO)) {
				if (inconsistent == null)
					inconsistent = new ArrayList();
				inconsistent.add(file);
			}
		}
		if (inconsistent == null)
			inconsistent = Collections.EMPTY_LIST;
		return inconsistent;
	}

	protected List getInconsistentResources() {
		List mofResources = provider.getResources();
		List inconsistent = null;
		int size = mofResources.size();
		Resource res = null;
		ReferencedResource refRes = null;
		for (int i = 0; i < size; i++) {
			res = (Resource) mofResources.get(i);
			if (WorkbenchResourceHelper.isReferencedResource(res)) {
				refRes = (ReferencedResource) res;
				if (!WorkbenchResourceHelper.isConsistent(refRes)) {
					if (inconsistent == null)
						inconsistent = new ArrayList();
					inconsistent.add(refRes);
				}
			}
		}
		if (inconsistent == null)
			inconsistent = Collections.EMPTY_LIST;
		return inconsistent;
	}

	protected List getFiles(List refResources) {
		List files = new ArrayList(refResources.size());
		IFile file = null;
		ReferencedResource refRes = null;
		for (int i = 0; i < refResources.size(); i++) {
			refRes = (ReferencedResource) refResources.get(i);
			file = WorkbenchResourceHelper.getFile(refRes);
			if (file != null)
				files.add(file);
		}
		return files;
	}

	/**
	 * This method should be called at least the first time a ResourceStateValidatorPresenter
	 * becomes active and is about to edit its contents. The returned IStatus may have an ERROR
	 * status which should be presented to the user.
	 */
	public IStatus validateState(ResourceStateValidatorPresenter presenter) throws CoreException {
		List roResources, nonResROFiles, roFiles = null;
		List[] readOnly = selectReadOnlyResources(provider.getResources());
		roResources = readOnly[0];
		roFiles = readOnly[1];
		nonResROFiles = selectReadOnlyFiles(provider.getNonResourceFiles());
		if (nonResROFiles != null) {
			if (roFiles == null)
				roFiles = nonResROFiles;
			else
				roFiles.addAll(nonResROFiles);
		}
		if (roFiles == null || roFiles.isEmpty())
			return OK_STATUS;
		IFile[] files = new IFile[roFiles.size()];
		roFiles.toArray(files);
		Object ctx = presenter != null ? presenter.getValidateEditContext() : null;
		IStatus result = ResourcesPlugin.getWorkspace().validateEdit(files, ctx);
		cacheValidateState(result, roResources, nonResROFiles);
		if (!result.isOK())
			checkConsistency(presenter);
		return result;
	}

	/**
	 * Method selectReadOnlyFiles.
	 * 
	 * @param list
	 * @param roFiles
	 */
	private List selectReadOnlyFiles(List files) {
		if (files == null || files.isEmpty())
			return files;
		int size = files.size();
		List readOnly = null;
		IFile file = null;
		for (int i = 0; i < size; i++) {
			file = (IFile) files.get(i);
			if (file.isReadOnly()) {
				if (readOnly == null)
					readOnly = new ArrayList(size);
				readOnly.add(file);
			}
		}
		return readOnly;
	}

	/**
	 * Method selectReadOnlyResources.
	 * 
	 * @param list
	 * @param roFiles
	 * @return List
	 */
	private List[] selectReadOnlyResources(List resources) {
		if (resources == null || resources.isEmpty())
			return new List[]{resources, null};
		IFile file = null;
		int size = resources.size();
		Resource res = null;
		List readOnly = null;
		List roFiles = null;
		for (int i = 0; i < size; i++) {
			res = (Resource) resources.get(i);
			file = WorkbenchResourceHelper.getFile(res);
			if (file != null && file.isReadOnly()) {
				if (readOnly == null)
					readOnly = new ArrayList(size);
				readOnly.add(res);
				if (roFiles == null)
					roFiles = new ArrayList(size);
				roFiles.add(file);
			}
		}
		return new List[]{readOnly, roFiles};
	}

	protected long computeModificationStamp(ReferencedResource resource) {
		return WorkbenchResourceHelper.computeModificationStamp(resource);
	}


	protected void refreshFiles(List someFiles, List inconsitentResources) throws CoreException {
		RefreshRunnable runnable = new RefreshRunnable(someFiles, inconsitentResources);
		ResourcesPlugin.getWorkspace().run(runnable, null);
		if (runnable.getThrownException() != null)
			throw runnable.getThrownException();
	}

	protected void primRefreshFiles(List someFiles) throws CoreException {
		int size = someFiles.size();
		IFile file = null;
		for (int i = 0; i < size; i++) {
			file = (IFile) someFiles.get(i);
			if (!file.isSynchronized(IResource.DEPTH_ZERO))
				file.refreshLocal(IResource.DEPTH_ONE, null);
			else
				refreshResource(file);
		}
	}

	/**
	 * We need to remove the Resource that corresponds to the <code>file</code> to force a
	 * refresh.
	 */
	protected void refreshResource(IFile file) {
		Resource res = WorkbenchResourceHelperBase.getResource(file);
		if (res != null)
			res.unload();
	}

	/**
	 * Force the resources to not be dirty to ensure that they will be removed from their
	 * ResourceSet when their file is refreshed.
	 */
	protected void prepareResourcesForRefresh(List refResources) {
		ReferencedResource res = null;
		for (int i = 0; i < refResources.size(); i++) {
			res = (ReferencedResource) refResources.get(i);
			res.setForceRefresh(true);
		}
	}

	/**
	 * Gets the lastNonRefreshStateMap.
	 * 
	 * @return Returns a Map
	 */
	protected Map getLastNonRefreshStateMap() {
		if (lastNonRefreshStateMap == null)
			lastNonRefreshStateMap = new HashMap();
		return lastNonRefreshStateMap;
	}
}
