//------------------------------------------------------------------------------
// 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.io.FileNotFoundException;
import java.io.FileOutputStream;
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(resource.getURI().toFileString());
		} 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 {
				refresh(path);
			} catch (CoreException 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;
	}
}
