/**********************************************************************
Copyright (c) 2000, 2002 IBM Corp. and others.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Common Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/cpl-v10.html

Contributors:
    IBM Corporation - Initial implementation
**********************************************************************/

package org.eclipse.ui.editors.text;


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.swt.widgets.Display;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.IWorkspace;
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.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;

import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.source.IAnnotationModel;

import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ContainerGenerator;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.texteditor.IElementStateListener;
import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;



/**
 * Shareable document provider specialized for file resources (<code>IFile</code>).<p>
 * This class may be instantiated or be subclassed.
 */
public class FileDocumentProvider extends StorageDocumentProvider {
	
	
	/**
	 * Runnable encapsulating an element state change. This runnable ensures 
	 * that a element change failed message is sent out to the element state listeners
	 * in case an exception occurred.
	 * @since 2.0
	 */
	protected class SafeChange implements Runnable {
		
		/** The input that changes. */
		private IFileEditorInput fInput;
		
		/**
		 * Creates a new safe runnable for the given input.
		 * @param input the input
		 */
		public SafeChange(IFileEditorInput input) {
			fInput= input;
		}
		
		/** 
		 * Subclass responsibility.
		 * @param input the input
		 * @exception Exception in case of error
		 */
		protected void execute(IFileEditorInput input) throws Exception {
		}
		
		/*
		 * @see java.lang.Runnable#run()
		 * @since 2.0
		 */
		public void run() {
			
			if (getElementInfo(fInput) == null) {
				fireElementStateChangeFailed(fInput);
				return;
			}
			
			try {
				execute(fInput);
			} catch (Exception e) {
				fireElementStateChangeFailed(fInput);
			}
		}
	};
	
	
	/**
	 * Synchronizes the document with external resource changes.
	 */
	protected class FileSynchronizer implements IResourceChangeListener, IResourceDeltaVisitor {
		
		/** The file editor input */
		protected IFileEditorInput fFileEditorInput;
		
		/**
		 * Creates a new file synchronizer. Is not yet installed on a resource.
		 * @param fileEditorInput the editor input to be synchronized
		 */
		public FileSynchronizer(IFileEditorInput fileEditorInput) {
			fFileEditorInput= fileEditorInput;
		};
		
		/**
		 * Creates a new file synchronizer. Is not yet installed on a resource.
		 * @param fileEditorInput the editor input to be synchronized
		 * @deprecated use FileSynchronizer(IFileEditorInput)
		 */
		public FileSynchronizer(FileEditorInput fileEditorInput) {
			fFileEditorInput= fileEditorInput;
		};
		
		/**
		 * Returns the file wrapped by the file editor input.
		 * @return the file wrapped by the editor input associated with that synchronizer
		 */
		protected IFile getFile() {
			return fFileEditorInput.getFile();
		}
		
		/**
		 * Installs the synchronizer on the input's file.
		 */
		public void install() {
			getFile().getWorkspace().addResourceChangeListener(this);
		}
		
		/**
		 * Uninstalls the synchronizer from the input's file.
		 */
		public void uninstall() {
			getFile().getWorkspace().removeResourceChangeListener(this);
		}
		
		/*
		 * @see IResourceChangeListener#resourceChanged(IResourceChangeEvent)
		 */
		public void resourceChanged(IResourceChangeEvent e) {
			IResourceDelta delta= e.getDelta();
			try {
				if (delta != null)
					delta.accept(this);
			} catch (CoreException x) {
				handleCoreException(x, TextEditorMessages.getString("FileDocumentProvider.resourceChanged")); //$NON-NLS-1$
			}
		}
		
		/*
		 * @see IResourceDeltaVisitor#visit(IResourceDelta)
		 */
		public boolean visit(IResourceDelta delta) throws CoreException {
						
			if (delta != null && getFile().equals(delta.getResource())) {
				
				Runnable runnable= null;
				
				switch (delta.getKind()) {
					case IResourceDelta.CHANGED:
						if ((IResourceDelta.CONTENT & delta.getFlags()) != 0) {
							FileInfo info= (FileInfo) getElementInfo(fFileEditorInput);
							if (!info.fCanBeSaved && computeModificationStamp(getFile()) != info.fModificationStamp) {
								runnable= new SafeChange(fFileEditorInput) {
									protected void execute(IFileEditorInput input) throws Exception {
										handleElementContentChanged(input);
									}
								};
							}
						}
						break;
					case IResourceDelta.REMOVED:
						if ((IResourceDelta.MOVED_TO & delta.getFlags()) != 0) {
							final IPath path= delta.getMovedToPath();
							runnable= new SafeChange(fFileEditorInput) {
								protected void execute(IFileEditorInput input) throws Exception {
									handleElementMoved(input, path);
								}
							};
						} else {
							FileInfo info= (FileInfo) getElementInfo(fFileEditorInput);
							if (!info.fCanBeSaved) {
								runnable= new SafeChange(fFileEditorInput) {
									protected void execute(IFileEditorInput input) throws Exception {
										handleElementDeleted(input);
									}
								};
							}
						}
						break;
				}
				
				if (runnable != null)
					update(runnable);
			}
			
			return true; // because we are sitting on files anyway
		}
		
		/**
		 * Posts the update code "behind" the running operation.
		 *
		 * @param runnable the update code
		 */
		protected void update(Runnable runnable) {
			
			if (runnable instanceof SafeChange)
				fireElementStateChanging(fFileEditorInput);
			
			IWorkbench workbench= PlatformUI.getWorkbench();
			IWorkbenchWindow[] windows= workbench.getWorkbenchWindows();
			if (windows != null && windows.length > 0) {
				Display display= windows[0].getShell().getDisplay();
				display.asyncExec(runnable);
			} else {
				runnable.run();
			}
		}
	};
	
	
	
	/**
	 * Bundle of all required information to allow files as underlying document resources. 
	 */
	protected class FileInfo extends StorageInfo {
		
		/** The file synchronizer */
		public FileSynchronizer fFileSynchronizer;
		/** The time stamp at which this provider changed the file */
		public long fModificationStamp= IResource.NULL_STAMP;
		
		/**
		 * Creates a new file info.
		 * @param document the document
		 * @param model the annotation model
		 * @param fileSynchronizer the file synchronizer
		 */
		public FileInfo(IDocument document, IAnnotationModel model, FileSynchronizer fileSynchronizer) {
			super(document, model);
			fFileSynchronizer= fileSynchronizer;
		}
	};
	
	
	/**
	 * Creates a new document provider.
	 */
	public FileDocumentProvider() {
		super();
	}
	
	/**
	 * Overrides <code>StorageDocumentProvider#setDocumentContent(IDocument, IEditorInput)</code>.
	 * @deprecated use file encoding based version
	 * @since 2.0
	 */
	protected boolean setDocumentContent(IDocument document, IEditorInput editorInput) throws CoreException {
		if (editorInput instanceof IFileEditorInput) {
			IFile file= ((IFileEditorInput) editorInput).getFile();
			setDocumentContent(document, file.getContents(false));
			return true;
		}
		return super.setDocumentContent(document, editorInput);
	}
	
	/*
	 * @see StorageDocumentProvider#setDocumentContent(IDocument, IEditorInput, String)
	 * @since 2.0
	 */
	protected boolean setDocumentContent(IDocument document, IEditorInput editorInput, String encoding) throws CoreException {
		if (editorInput instanceof IFileEditorInput) {
			IFile file= ((IFileEditorInput) editorInput).getFile();
			setDocumentContent(document, file.getContents(false), encoding);
			return true;
		}
		return super.setDocumentContent(document, editorInput, encoding);
	}
	
	/*
	 * @see AbstractDocumentProvider#createAnnotationModel(Object)
	 */
	protected IAnnotationModel createAnnotationModel(Object element) throws CoreException {
		if (element instanceof IFileEditorInput) {
			IFileEditorInput input= (IFileEditorInput) element;
			return new ResourceMarkerAnnotationModel(input.getFile());
		}
		
		return super.createAnnotationModel(element);
	}
	
	/**
	 * Checks whether the given resource has been changed on the 
	 * local file system by comparing the actual time stamp with the 
	 * cached one. If the resource has been changed, a <code>CoreException</code>
	 * is thrown.
	 * 
	 * @param cachedModificationStamp the chached modification stamp
	 * @param resource the resource to check
	 * @exception CoreException if resource has been changed on the file system
	 */
	protected void checkSynchronizationState(long cachedModificationStamp, IResource resource) throws CoreException {
		if (cachedModificationStamp != computeModificationStamp(resource)) {
			Status status= new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IResourceStatus.OUT_OF_SYNC_LOCAL, TextEditorMessages.getString("FileDocumentProvider.error.out_of_sync"), null); //$NON-NLS-1$
			throw new CoreException(status);
		}
	}
	
	/**
	 * Computes the initial modification stamp for the given resource.
	 * 
	 * @param resource the resource
	 * @return the modification stamp
	 */
	protected long computeModificationStamp(IResource resource) {
		long modificationStamp= resource.getModificationStamp();
		
		IPath path= resource.getLocation();
		if (path == null)
			return modificationStamp;
			
		modificationStamp= path.toFile().lastModified();
		return modificationStamp;
	}
	
	/*
	 * @see IDocumentProvider#getModificationStamp(Object)
	 */
	public long getModificationStamp(Object element) {
		
		if (element instanceof IFileEditorInput) {
			IFileEditorInput input= (IFileEditorInput) element;
			return computeModificationStamp(input.getFile());
		}
		
		return super.getModificationStamp(element);
	}
	
	/*
	 * @see IDocumentProvider#getSynchronizationStamp(Object)
	 */
	public long getSynchronizationStamp(Object element) {
		
		if (element instanceof IFileEditorInput) {
			FileInfo info= (FileInfo) getElementInfo(element);
			return info.fModificationStamp;
		}
		
		return super.getSynchronizationStamp(element);
	}
	
	/*
	 * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#synchronize(Object)
	 * @since 2.0
	 */
	public void synchronize(Object element)  throws CoreException {
		if (element instanceof IFileEditorInput) {
			
			IFileEditorInput input= (IFileEditorInput) element;
			
			FileInfo info= (FileInfo) getElementInfo(element);
			if (info != null) {
					
				info.fFileSynchronizer.uninstall();
				input.getFile().refreshLocal(IResource.DEPTH_INFINITE, null);
				info.fFileSynchronizer.install();			
				
				handleElementContentChanged((IFileEditorInput) element);
			}
			return;
			
		}
		super.synchronize(element);
	}
	
	/*
	 * @see IDocumentProvider#isDeleted(Object)
	 */
	public boolean isDeleted(Object element) {
		
		if (element instanceof IFileEditorInput) {
			IFileEditorInput input= (IFileEditorInput) element;
			
			IPath path= input.getFile().getLocation();
			if (path == null)
				return true;
				
			return !path.toFile().exists();
		}
		
		return super.isDeleted(element);
	}
	
	/*
	 * @see AbstractDocumentProvider#doSaveDocument(IProgressMonitor, Object, IDocument, boolean)
	 */
	protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException {
		if (element instanceof IFileEditorInput) {
			
			IFileEditorInput input= (IFileEditorInput) element;
			
			try {
			
			InputStream stream= new ByteArrayInputStream(document.get().getBytes(ResourcesPlugin.getEncoding()));
			IFile file= input.getFile();
									
				if (file.exists()) {
					
					FileInfo info= (FileInfo) getElementInfo(element);
					
					if (info != null && !overwrite)
						checkSynchronizationState(info.fModificationStamp, file);
					
					// inform about the upcoming content change
					fireElementStateChanging(element);
					try {
						file.setContents(stream, overwrite, true, monitor);
					} catch (CoreException x) {
						// inform about failure
						fireElementStateChangeFailed(element);
						throw x;
					} catch (RuntimeException x) {
						// inform about failure
						fireElementStateChangeFailed(element);
						throw x;
					}
					
					// If here, the editor state will be flipped to "not dirty".
					// Thus, the state changing flag will be reset.
					
					if (info != null) {
											
						ResourceMarkerAnnotationModel model= (ResourceMarkerAnnotationModel) info.fModel;
						model.updateMarkers(info.fDocument);
						
						info.fModificationStamp= computeModificationStamp(file);
					}
					
				} else {
					try {
						monitor.beginTask(TextEditorMessages.getString("FileDocumentProvider.task.saving"), 2000); //$NON-NLS-1$
						ContainerGenerator generator = new ContainerGenerator(file.getParent().getFullPath());
						generator.generateContainer(new SubProgressMonitor(monitor, 1000));
						file.create(stream, false, new SubProgressMonitor(monitor, 1000));
					}
					finally {
						monitor.done();
					}
				}
				
			} catch (IOException x) {
				IStatus s= new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, x.getMessage(), x);
				throw new CoreException(s);
			}
			
		} else {
			super.doSaveDocument(monitor, element, document, overwrite);
		}
	}
	
	/*
	 * @see AbstractDocumentProvider#createElementInfo(Object)
	 */
	protected ElementInfo createElementInfo(Object element) throws CoreException {
		if (element instanceof IFileEditorInput) {
			
			IFileEditorInput input= (IFileEditorInput) element;
			
			try {
				input.getFile().refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
			} catch (CoreException x) {
				handleCoreException(x,TextEditorMessages.getString("FileDocumentProvider.createElementInfo")); //$NON-NLS-1$
			}
			
			IDocument d= null;
			IStatus s= null;
			
			try {
				d= createDocument(element);
			} catch (CoreException x) {
				s= x.getStatus();
				d= new Document();
			}
			
			IAnnotationModel m= createAnnotationModel(element);
			FileSynchronizer f= new FileSynchronizer(input);
			f.install();
			
			FileInfo info= new FileInfo(d, m, f);
			info.fModificationStamp= computeModificationStamp(input.getFile());
			info.fStatus= s;
			
			return info;
		}
		
		return super.createElementInfo(element);
	}
	
	/*
	 * @see AbstractDocumentProvider#disposeElementInfo(Object, ElementInfo)
	 */
	protected void disposeElementInfo(Object element, ElementInfo info) {
		if (info instanceof FileInfo) {
			FileInfo fileInfo= (FileInfo) info;
			if (fileInfo.fFileSynchronizer != null)
				fileInfo.fFileSynchronizer.uninstall();
		}
		
		super.disposeElementInfo(element, info);
	}	
	
	/**
	 * Updates the element info to a change of the file content and sends out
	 * appropriate notifications.
	 *
	 * @param fileEditorInput the input of an text editor
	 */
	protected void handleElementContentChanged(IFileEditorInput fileEditorInput) {
		FileInfo info= (FileInfo) getElementInfo(fileEditorInput);
		
		IDocument document= new Document();
		IStatus status= null;
		
		try {
			
			try {
				fileEditorInput.getFile().refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
			} catch (CoreException x) {
				handleCoreException(x, "FileDocumentProvider.handleElementContentChanged"); //$NON-NLS-1$
			}
			
			setDocumentContent(document, fileEditorInput, info.fEncoding);
			
		} catch (CoreException x) {
			status= x.getStatus();
		}
		
		String newContent= document.get();
		
		if ( !newContent.equals(info.fDocument.get())) {
			
			// set the new content and fire content related events
			fireElementContentAboutToBeReplaced(fileEditorInput);
			
			removeUnchangedElementListeners(fileEditorInput, info);
			
			info.fDocument.removeDocumentListener(info);
			info.fDocument.set(newContent);
			info.fCanBeSaved= false;
			info.fModificationStamp= computeModificationStamp(fileEditorInput.getFile());
			info.fStatus= status;
			
			addUnchangedElementListeners(fileEditorInput, info);
			
			fireElementContentReplaced(fileEditorInput);
			
		} else {
			
			removeUnchangedElementListeners(fileEditorInput, info);
			
			// fires only the dirty state related event
			info.fCanBeSaved= false;
			info.fModificationStamp= computeModificationStamp(fileEditorInput.getFile());
			info.fStatus= status;
			
			addUnchangedElementListeners(fileEditorInput, info);
			
			fireElementDirtyStateChanged(fileEditorInput, false);
		}
	}
	
	/**
	 * Sends out the notification that the file serving as document input has been moved.
	 * 
	 * @param fileEditorInput the input of an text editor
	 * @param path the path of the new location of the file
	 */
	protected void handleElementMoved(IFileEditorInput fileEditorInput, IPath path) {
		IWorkspace workspace= ResourcesPlugin.getWorkspace();
		IFile newFile= workspace.getRoot().getFile(path);
		fireElementMoved(fileEditorInput, newFile == null ? null : new FileEditorInput(newFile));
	}
	
	/**
	 * Sends out the notification that the file serving as document input has been deleted.
	 *
	 * @param fileEditorInput the input of an text editor
	 */
	protected void handleElementDeleted(IFileEditorInput fileEditorInput) {
		fireElementDeleted(fileEditorInput);
	}
	
	/*
	 * @see AbstractDocumentProvider#getElementInfo(Object)
	 * It's only here to circumvent visibility issues with certain compilers.
	 */
	protected ElementInfo getElementInfo(Object element) {
		return super.getElementInfo(element);
	}
	
	/*
	 * @see AbstractDocumentProvider#doValidateState(Object, Object)
	 * @since 2.0
	 */
	protected void doValidateState(Object element, Object computationContext) throws CoreException {
		
		if (element instanceof IFileEditorInput) {
			IFileEditorInput input= (IFileEditorInput) element;
			FileInfo info= (FileInfo) getElementInfo(input);
			if (info != null) {
				IFile file= input.getFile();
				if (file.isReadOnly()) { // do not use cached state here
					IWorkspace workspace= file.getWorkspace();
					workspace.validateEdit(new IFile[] { file }, computationContext);
				}
			}
		}
		
		super.doValidateState(element, computationContext);
	}
	
	/*
	 * @see IDocumentProviderExtension#isModifiable(Object)
	 * @since 2.0
	 */
	public boolean isModifiable(Object element) {
		if (!isStateValidated(element)) {
			if (element instanceof IFileEditorInput)
				return true;
		}
		return super.isModifiable(element);
	}
	
	/*
	 * @see IDocumentProvider#resetDocument(Object)
	 * @since 2.0
	 */
	public void resetDocument(Object element) throws CoreException {
		// http://dev.eclipse.org/bugs/show_bug.cgi?id=19014
		if (element instanceof IFileEditorInput) {
			IFileEditorInput input= (IFileEditorInput) element;
			try {
				input.getFile().refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
			} catch (CoreException x) {
				handleCoreException(x,TextEditorMessages.getString("FileDocumentProvider.resetDocument")); //$NON-NLS-1$
			}
		}
		super.resetDocument(element);	
	}
}