//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 java.security.AccessController;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.core.internal.resources.ResourceException;
import org.eclipse.core.internal.resources.ResourceStatus;
import org.eclipse.core.internal.utils.Messages;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
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.emf.workspace.util.WorkspaceSynchronizer;
import org.eclipse.epf.persistence.util.PersistenceResources;
import org.eclipse.epf.services.IFileManager;
import org.eclipse.osgi.util.NLS;

import sun.security.action.GetPropertyAction;

/**
 * Implementation class for IFileManager.
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class FileManager implements IFileManager {

	public static final String PLUGIN_ID = FileManager.class.getPackage()
			.getName();

	private static FileManager instance = null;

	private static String tmpdir;

	public static String getTempDir() {
		if (tmpdir == null) {
			GetPropertyAction a = new GetPropertyAction("java.io.tmpdir"); //$NON-NLS-1$
			tmpdir = ((String) AccessController.doPrivileged(a));
		}
		return tmpdir;
	}

	private boolean validateEditInitialized = false;

	public static final FileManager getInstance() {
		if (instance == null) {
			synchronized (FileManager.class) {
				if (instance == null) {
					instance = new FileManager();
				}
			}
		}

		return instance;
	}

	protected FileManager() {
	}

	public static IResource getResourceForLocation(String location) {
		File file = new File(location);
		if (!file.exists()) {
			return null;
		}
		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
		IPath path = new Path(location);
		IResource resource;
		if (file.isFile()) {
			resource = workspaceRoot.getFileForLocation(path);
			if (resource == null) {
				IResource parentResource = getResourceForLocation(file
						.getParent());
				if (parentResource != null) {
					try {
						parentResource.refreshLocal(IResource.DEPTH_ONE, null);
					} catch (CoreException e) {
//						CommonPlugin.INSTANCE.log(e);
					}
					resource = workspaceRoot.getFileForLocation(path);
				}
			}
		} else {
			resource = workspaceRoot.getContainerForLocation(path);
		}
		return resource;
	}

	public static boolean refresh(IResource resource) throws CoreException {
		if (!resource.exists()) {
			ArrayList foldersToRefresh = new ArrayList();
			IContainer container;
			for (container = resource.getParent(); !container.exists(); container = container
					.getParent()) {
				foldersToRefresh.add(0, container);
			}
			if (container.exists()) {
				container.refreshLocal(IResource.DEPTH_ONE, null);
			}
			if (!foldersToRefresh.isEmpty()) {
				for (Iterator iter = foldersToRefresh.iterator(); iter
						.hasNext();) {
					IFolder folder = (IFolder) iter.next();
					if (folder.exists()) {
						folder.refreshLocal(IResource.DEPTH_ONE, null);
					} else {
						return false;
					}
				}
			}
		}
		resource.refreshLocal(IResource.DEPTH_ONE, null);
		return true;
	}

	/**
	 * Refreshes file or directory with given local file system
	 * <code>path</code>
	 * 
	 * @param path
	 *            local file system path
	 * @return
	 * @throws CoreException
	 */
	private static boolean refresh(String path) throws CoreException {
		IResource resource = getResourceForLocation(path);
		if (resource != null) {
			return refresh(resource);
		}
		return false;
	}

	public boolean refresh(Resource resource) {
		try {
			return refresh(toFileString(resource.getURI()));
		} catch (CoreException e) {
//			CommonPlugin.INSTANCE.log(e);
			return false;
		}
	}

	public boolean move(String oldPath, String newPath) {
		return move(oldPath, newPath, false);
	}

	public boolean move(String oldPath, String newPath,
			boolean forceRemoveSource) {
		try {
			refresh(oldPath);

			IResource resource = null;
			IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace()
					.getRoot();

			// create the folders of the destination if they did not exist
			IPath destPath = new Path(newPath);
			if (new File(oldPath).isFile()) {
				resource = workspaceRoot.getFileForLocation(destPath);
				if(resource == null) {
					resource = workspaceRoot.getContainerForLocation(destPath);
				}
			} else {				
				resource = workspaceRoot.getContainerForLocation(destPath);
				if(resource == null) {
					resource = workspaceRoot.getFileForLocation(destPath);
				}
			}	
			if(resource != null) {
				if (resource.exists()) {
					resource.refreshLocal(IResource.DEPTH_ZERO, null);
					if(resource.exists()) {
						throw new MultiFileIOException(NLS.bind(
								PersistenceResources.moveError_msg, oldPath, newPath));
					}
				}
				ArrayList foldersToCreate = new ArrayList();
				IContainer container;
				for (container = resource.getParent(); !container.exists(); container = container
				.getParent()) {
					foldersToCreate.add(0, container);
				}
				if (!foldersToCreate.isEmpty()) {
					container.refreshLocal(IResource.DEPTH_ONE, null);
					for (Iterator iter = foldersToCreate.iterator(); iter.hasNext();) {
						IFolder folder = (IFolder) iter.next();
						if (!folder.exists()) {
							folder.create(true, true, null);
						} else {
							folder.refreshLocal(IResource.DEPTH_ONE, null);
						}
					}
				}
				destPath = resource.getFullPath();
			}
			else if(Platform.getLocation().isPrefixOf(destPath)) {
				destPath = new Path(destPath.toOSString().substring(Platform.getLocation().toOSString().length()));						
			}
			
			IPath path = new Path(oldPath);
			IFile file = workspaceRoot.getFileForLocation(path);
			if (file != null && file.exists()) {
				resource = file;
			} else {
				resource = workspaceRoot.getContainerForLocation(path);
			}
			if (resource != null) {
				try {
					resource.move(destPath, true, null);
				} catch (ResourceException e) {
					PersistencePlugin.getDefault().getLog().log(e.getStatus());
					
					if (forceRemoveSource) {
						throw e;
					}

					boolean failed = false;

					// handle situation when Eclipse moves file/directory by
					// copying it to destination then deleting the source
					// but deletion failed
					IStatus[] statuses = e.getStatus().getChildren();
					for (int i = 0; i < statuses.length; i++) {
						IStatus status = statuses[i];
						if (status.getCode() == IResourceStatus.FAILED_DELETE_LOCAL
								&& status.getMessage() == Messages.localstore_deleteProblem) {
							String msg = MessageFormat
									.format(
											"Warning while moving ''{0}'' to ''{1}'': {2}", new Object[] { oldPath, newPath, status.getMessage() }); //$NON-NLS-1$
							PersistencePlugin.getDefault().getLogger().logWarning(msg);
						} else {
							failed = true;
						}
					}
					if (failed || !new File(newPath).exists()) {
						return false;
					}
				}
				return true;
			}
		} catch (CoreException e) {
			PersistencePlugin.getDefault().getLogger().logError(e);
			if (MultiFileSaveUtil.DEBUG) {
				e.printStackTrace();
			}
		}
		return false;
	}

	public boolean rename(File oldFile, File newFile) {
		return move(oldFile.getAbsolutePath(), newFile.getAbsolutePath());
	}

	public void deleteResource(String path, IProgressMonitor monitor)
			throws CoreException {
		// no need to refresh the whole tree from specified path
		// getResourceForLocation() refreshes resource in a more efficient way
		//
		// IWorkspaceRoot workspaceRoot =
		// ResourcesPlugin.getWorkspace().getRoot();
		// try {
		// workspaceRoot.refreshLocal(IResource.DEPTH_INFINITE, monitor);
		// } catch (CoreException e1) {
		// e1.printStackTrace();
		// }

		IResource resource = getResourceForLocation(path);
		if (resource != null) {
			resource.delete(true, monitor);
		}
	}

	public boolean delete(String path) {
		try {
			deleteResource(path, null);
			return true;
		} catch (CoreException e) {
			CommonPlugin.INSTANCE.log(e);
			if (MultiFileSaveUtil.DEBUG) {
				e.printStackTrace();
			}
		}
		return false;
	}

	private static boolean fromCC(IStatus status) {
		String pluginId = status.getPlugin();
		return pluginId != null
				&& pluginId.toLowerCase().indexOf("clearcase") != -1; //$NON-NLS-1$
	}

	public IStatus checkModify(String[] paths, Object context) {
		IStatus status = null;
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		IFile[] files = new IFile[paths.length];
		ArrayList<String> notFoundFiles = new ArrayList<String>();
		for (int i = 0; i < paths.length; i++) {
			String path = paths[i];
			try {
				path = new File(path).getCanonicalPath();
				refresh(path);
			} catch (Exception e) {
				PersistencePlugin.getDefault().getLogger().logError(e);
			}
			IFile file = workspace.getRoot().getFileForLocation(new Path(path));
			if (file == null) {
				notFoundFiles.add(path);
			} else {
				files[i] = file;
			}
		}
		if (!notFoundFiles.isEmpty()) {
			return new Status(IStatus.WARNING, PLUGIN_ID, IStatus.WARNING, NLS
					.bind(PersistenceResources.fileNotFoundError_msg,
							notFoundFiles), null);
		}

		if (!validateEditInitialized) {
			status = workspace.validateEdit(files, context);
			validateEditInitialized = true;
			if (status.isOK()) {
				// double-check after initialization
				//
				status = workspace.validateEdit(files, context);
			}
		} else {
			status = workspace.validateEdit(files, context);
		}

		if (status.isOK()) {
			MultiStatus multiStatus = new MultiStatus(PLUGIN_ID,
					IStatus.OK, PersistenceResources.modifyFilesError_msg,
					null);

			// some version control provider still returns OK status even though
			// user cancelled the check out
			// double-check here again to make sure the file is not read-only
			//			
			for (int i = 0; i < files.length; i++) {
				IFile file = files[i];
				try {
					file.refreshLocal(IResource.DEPTH_ZERO, null);
				} catch (CoreException e) {
					CommonPlugin.INSTANCE.log(e);
				}
				if (file.isReadOnly()) {
					String localPath = file.getLocation().toOSString();
					String msg = MessageFormat.format(
							PersistenceResources.FileManager_fileReadOnly,
							new Object[] { localPath });
					multiStatus.add(new ResourceStatus(IStatus.ERROR, 0, file
							.getFullPath(), msg, null));
				}
			}
			if(!multiStatus.isOK()) {
				return multiStatus;
			}
		} else {
			// hack for clearcase
			if (fromCC(status)) {
				String msg = PersistenceResources.modifyFilesError_msg;
				MultiStatus multiStatus = new MultiStatus(PLUGIN_ID, status
						.getCode(), msg, null);
				multiStatus.add(status);
				return multiStatus;
			}
		}

		// convert workspace path to local file system path
		if (status instanceof MultiStatus) {
			MultiStatus ms = (MultiStatus) status;
			for (int i = 0; i < ms.getChildren().length; i++) {
				IStatus childStatus = ms.getChildren()[i];
				ms.getChildren()[i] = toStatusWithLocalPath(childStatus);
			}
		}
		else {
			status = toStatusWithLocalPath(status);
		}

		return status;
	}
	
	private static IStatus toStatusWithLocalPath(IStatus status) {
		if (status instanceof IResourceStatus
				&& status.getCode() == IResourceStatus.READ_ONLY_LOCAL) {
			IResourceStatus resourceStatus = ((IResourceStatus) status);
			IPath path = resourceStatus.getPath();
			IFile file = ResourcesPlugin.getWorkspace().getRoot()
					.getFile(path);
			String localPath = file.getLocation().toOSString();
			String msg = MessageFormat.format(
					PersistenceResources.FileManager_fileReadOnly,
					new Object[] { localPath }); 
			return new ResourceStatus(status
					.getSeverity(), status.getCode(),
					resourceStatus.getPath(), msg, status
							.getException());
		}
		return status;
	}

	/**
	 * @see org.eclipse.epf.services.IFileManager#checkModify(java.lang.String,
	 *      java.lang.Object)
	 */
	public IStatus checkModify(String path, Object context) {
		return checkModify(new String[] { path }, context);
	}

	/**
	 * Checks if the given path is team-private file or folder
	 * 
	 * @param path
	 * @return
	 */
	public boolean isTeamPrivate(String path) {
		IResource resource = getResourceForLocation(path);
		return resource != null && resource.isTeamPrivateMember();
	}

    /**
     * Finds the file corresponding to the specified URI, using a URI converter
     * if necessary (and provided) to normalize it.
     * 
     * @param uri a URI
     * @param converter an optional URI converter (may be <code>null</code>)
     * 
     * @return the file, if available in the workspace
     */
    public static IFile getFile(URI uri, URIConverter converter) {
        IFile result = null;
        
        if ("platform".equals(uri.scheme()) && (uri.segmentCount() > 2)) { //$NON-NLS-1$
            if ("resource".equals(uri.segment(0))) { //$NON-NLS-1$
                IPath path = new Path(URI.decode(uri.path())).removeFirstSegments(1);
                
                result = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
            }
        } else if (uri.isFile() && !uri.isRelative()) {
            result = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(
                new Path(uri.toFileString()));
        } else {
            // normalize, to see whether may we can resolve it this time
            if (converter != null) {
                URI normalized = converter.normalize(uri);
                
                if (!uri.equals(normalized)) {
                    // recurse on the new URI
                    result = getFile(normalized, converter);
                }
            }
        }
        
        return result;
    }

	public static String toFileString(URI uri, URIConverter converter) {
		if(uri.isFile()) {
			return uri.toFileString();
		}
		IFile file = getFile(uri, converter);
		return file != null ? file.getLocation().toOSString() : null;
	}
	
	public static String toFileString(URI uri) {
		return toFileString(uri, null);
	}
	
	public static class FileInfo implements IFileInfo {
		
		private IFile file;

		private FileInfo(IFile file) {
			this.file = file;
		}

		public long getModificationStamp() {
			return file.getModificationStamp();
		}

		public boolean isSynchronized() {
			return file.isSynchronized(IResource.DEPTH_ZERO);
		}

		public File getFile() {
			IPath loc = file.getLocation();
			return loc != null ? file.getLocation().toFile() : null;
		}
		
	}
	
	public IFileInfo getFileInfo(Resource resource) {
		IFile file = WorkspaceSynchronizer.getFile(resource);
		return file != null ? new FileInfo(file) : null;
	}
}
