/*******************************************************************************
 * Copyright (c) 2003, 2019 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * 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;
		}

		@Override
		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.
	 */
	@Override
	public void checkActivation(ResourceStateValidatorPresenter presenter) throws CoreException {
		checkConsistency(presenter);
	}

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

	@Override
	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()
	 */
	@Override
	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) && (refRes.isLoaded() && !refRes.isNew())) {
					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.
	 */
	@Override
	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;
	}
}
