//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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;

import java.io.File;

import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.persistence.util.PersistenceResources;
import org.eclipse.osgi.util.NLS;

/**
 * @author Phong Nguyen Le
 *
 * @since 1.2
 */
public class FailSafePersistenceHelper {
	private URI finalURI;
	private URI oldURI;
	private String currentTxID;
	private Resource resource;
	private URI tempURI;
	private String id;
	private String backupFile;
	private URIConverter converter;
	private boolean commitEmptyResource;
	
	public FailSafePersistenceHelper(Resource resource, String id) {
		this.resource = resource; 
		this.id = id;
		this.converter = resource.getResourceSet() != null ? resource.getResourceSet().getURIConverter() : null;
	}
	
	public void setCommitEmptyResource(boolean commitEmptyResource) {
		this.commitEmptyResource = commitEmptyResource;
	}

	/**
	 * Sets the temporary URI to save this resource to and it will be renamed to
	 * the original URI when saving is done
	 */
	public URI setTempURI(String txID) {
		if (finalURI == null) {
			finalURI = oldURI = resource.getURI();
			currentTxID = txID;

			tempURI = createTempURI();
			resource.setURI(tempURI);
		}
		return tempURI;
	}
	
	private URI createTempURI() {
		return URI.createFileURI(new StringBuffer(MultiFileXMIResourceImpl.getTempDir()).append(
				File.separator).append(currentTxID)
				.append("new").append(id).toString()); //$NON-NLS-1$
	}
	
	public String getBackupFilePath() {
		String backupFile = new StringBuffer(MultiFileXMIResourceImpl.getTempDir())
				.append(File.separator)
				.append(currentTxID)
				.append("old").append(id).toString(); //$NON-NLS-1$
		return backupFile;
	}
	
	private String toFileString(URI uri) {
		return FileManager.toFileString(uri, converter);
	}
	
	public void commit() {
		if (finalURI != null && (commitEmptyResource || !resource.getContents().isEmpty())) {
			File finalFile = new File(toFileString(finalURI));
			boolean wasMove = !oldURI.equals(finalURI);
			if (wasMove) {
			} else {
				// back up the file
				//
				String backup = getBackupFilePath();
				File bakFile = new File(backup);

				// trying to delete the old backup file if it exists
				//
				if (bakFile.exists()) {
					bakFile.delete();
				}

				if (finalFile.exists()) {
					// some CM provider like ClearCase renamed the versioned
					// file it its repository as soon as user renamed the file
					// in the workspace. To avoid this, use only regular rename
					// routine of java.io.File instead of IResource routine
					//
					if (FileUtil.moveFile(finalFile, bakFile)) {
						backupFile = backup;
					} else {
						String msg = NLS.bind(
								PersistenceResources.renameError_msg,
								finalFile, backup);
						throw new MultiFileIOException(msg);
					}
				}
			}

			// rename the resource file to the original name
			//
			File currentFile = new File(wasMove ? toFileString(oldURI)
					: toFileString(resource.getURI()));
			boolean success = false;
			if (wasMove) {
				success = MultiFileSaveUtil.move(resource, currentFile, finalFile);
			} else {
				// some CM provider like ClearCase renamed the versioned file it
				// its repository as soon as user renamed the file
				// in the workspace. To avoid this, use only regular rename
				// routine of java.io.File instead of IResource routine
				//
				success = FileUtil.moveFile(currentFile, finalFile);
			}
			if (!success) {
				String msg = NLS.bind(PersistenceResources.renameError_msg,
						currentFile, finalFile);
				throw new MultiFileIOException(msg);
			} else {
				if (wasMove) {
					didMove();
				}
			}
		}
	}

	/**
	 * Subclass to override to handle post move
	 */
	protected void didMove() {
	}

	public void deleteBackup() {
		if (backupFile != null) {
			try {
				// FileManager.getInstance().delete(backupFile);
				new File(backupFile).delete();
				backupFile = null;
			} catch (Throwable e) {
				CommonPlugin.INSTANCE.log(e);
				if (MultiFileSaveUtil.DEBUG) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public boolean hasTempURI() {
		if (currentTxID != null) {
			return createTempURI().equals(resource.getURI());
		}
		return false;
	}

	public URI getFinalURI() {
		if (finalURI != null) {
			return finalURI;
		}
		return resource.getURI();
	}

	public boolean restore() {
		File src = null, dest = null;
		boolean moved = false;
		if (backupFile != null) {
			src = new File(backupFile);
			dest = new File(toFileString(getFinalURI()));
		} else {
			moved = oldURI != null && !oldURI.equals(finalURI);
			if (moved) {
				File file = new File(toFileString(getFinalURI()));
				dest = new File(toFileString(oldURI));
				moved = file.exists() && !dest.exists();
				if (moved) {
					src = file;
				}
			}
		}
		if (src != null) {
			if (dest.exists()) {
				FileUtil.moveFile(dest,new File(toFileString(resource.getURI())));
			}
			boolean success;
			if (moved) {
				success = MultiFileSaveUtil.move(resource, src, dest);
				// if(success) {
				// MultiFileSaveUtil.updateURIMappings(this, null);
				// }
			} else {
				success = FileUtil.moveFile(src,dest);
			}
			if (!success) {
				throw new MultiFileIOException(NLS.bind(
						PersistenceResources.restoreResourceError_msg, this));
			}
			return true;
		}
		return false;
	}

	public void txFinished(boolean successful) {
//		boolean wasMove = !oldURI.equals(finalURI);
		if (successful) {
			resource.setURI(finalURI);
			resource.setModified(false);
//			updateTimeStamps();
			FileManager.getInstance().refresh(resource);
//			if(!wasMove) {
//				MultiFileResourceSetImpl resourceSet = (MultiFileResourceSetImpl) getResourceSet();
//				if(resourceSet != null) {
//					resourceSet.getUnresolvedProxyMarkerManager().validateMarkers(this);
//				}
//			}
		} else {
			restoreURI();
//			if (wasMove) {
//				// restore uri of ResourceDescriptor of this resource
//				//
//				MultiFileSaveUtil.updateURIMappings(this, oldURI, null, true);
//			}
		}
//		if (oldURI != null) {
//			MultiFileResourceSetImpl resourceSet = (MultiFileResourceSetImpl) getResourceSet();
//			if (resourceSet != null) {
//				resourceSet.getURIToTempURIMap().remove(oldURI);
//			}
//			oldURI = null;
//		}
		currentTxID = null;
		finalURI = null;
	}

	/**
	 * Restores the resource URI to the original one. This method must be call
	 * after saving regarless of its success.
	 * 
	 */
	private void restoreURI() {
		if (oldURI != null) {
			resource.setURI(oldURI);
		}
	}

}
