//------------------------------------------------------------------------------
// 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;
	
	public FailSafePersistenceHelper(Resource resource, String id) {
		this.resource = resource; 
		this.id = id;
		this.converter = resource.getResourceSet() != null ? resource.getResourceSet().getURIConverter() : null;
	}

	/**
	 * 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 && !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(this);
//			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);
		}
	}

}
