/***************************************************************************************************
 * Copyright (c) 2003, 2004 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.wst.common.internal.emf.resource.ReferencedResource;
import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;

import com.ibm.wtp.emf.workbench.WorkbenchResourceHelperBase;

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