/**
 * 
 */
package org.eclipse.epf.diagramming.base.providers;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.filebuffers.manipulation.ContainerCreator;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.workspace.AbstractEMFOperation;
import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
import org.eclipse.epf.diagram.core.part.DiagramFileEditorInputProxy;
import org.eclipse.epf.diagram.core.part.IDiagramFileEditorInputProxy;
import org.eclipse.epf.diagramming.base.DiagrammingResources;
import org.eclipse.epf.diagramming.base.persistence.DiagramPersister;
import org.eclipse.epf.diagramming.base.persistence.DiagramService;
import org.eclipse.epf.diagramming.base.persistence.ISaveEventDispatcher;
import org.eclipse.epf.diagramming.base.persistence.ISaveInfo;
import org.eclipse.epf.diagramming.base.persistence.SaveEventDispatcher;
import org.eclipse.epf.diagramming.base.persistence.SaveInfo;
import org.eclipse.epf.diagramming.base.util.UmaUmlUtil;
import org.eclipse.epf.diagramming.part.EPFDiagramEditorPlugin;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.DiagramModificationListener;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDiagramDocument;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDocument;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide.document.FileDiagramDocumentProvider;
import org.eclipse.gmf.runtime.emf.core.resources.GMFResource;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.uml2.uml.Activity;
import org.eclipse.uml2.uml.NamedElement;

/**
 * Specialized document provider for handle changes and manipulate document associated 
 * and synchronize the other opened editor's document and do merge any conflict synchronize.
 * Also handles the timestamp synchronization if the multiple editors are sharing same resource.
 * @author Shashidhar Kannoori
 */
public class DiagramEditorDocumentProvider extends FileDiagramDocumentProvider {

	/**
	 * 
	 */
	public DiagramEditorDocumentProvider() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide.document.FileDiagramDocumentProvider#setDocumentContent(org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDocument, org.eclipse.ui.IEditorInput)
	 * 
	 * @modified
	 */
	protected boolean setDocumentContent(IDocument document,
			IEditorInput editorInput) throws CoreException {
		if (editorInput instanceof DiagramFileEditorInputProxy) {
			DiagramFileEditorInputProxy diagramElement = (DiagramFileEditorInputProxy) editorInput;

			((IDiagramDocument) document).setEditingDomain(diagramElement
					.getEditingDomain());
			if (editorInput instanceof IStorageEditorInput) {
				IStorage storage = ((IStorageEditorInput) editorInput)
						.getStorage();
				setDocumentContentFromStorage(document, storage, editorInput);
				return true;
			}
		}
		return false;
	}

	protected void setupDocument(Object element, IDocument document) {
		super.setupDocument(element, document);
	}

	/**
	 * (non-Javadoc)
	 * @custom
	 */
	protected void setDocumentContentFromStorage(IDocument document,
			IStorage storage, IEditorInput editorInput) throws CoreException {
		Diagram diagram = (Diagram) document.getContent();
		if (diagram != null) {
			Resource resource = diagram.eResource();
			IFile resourceFile = WorkspaceSynchronizer.getFile(resource);
			// unload if the resourceFile and storage is same.
			// if not same throw exception.
			if (resourceFile != null) {
				if (resourceFile.equals(storage)) {
					document.setContent(null);
				} else {
					throw new CoreException(
							new Status(
									IStatus.ERROR,
									"1",
									1,
									DiagrammingResources.FileDocumentProvider_handleElementContentChanged,
									null));
				}
			}
		}
		IDiagramDocument diagramDocument = (IDiagramDocument) document;
		TransactionalEditingDomain domain = diagramDocument.getEditingDomain();

		diagram = DiagramPersister.load(domain, storage, true,
				getProgressMonitor(), editorInput);
		document.setContent(diagram);
		//super.setDocumentContentFromStorage(document, storage);
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide.document.FileDiagramDocumentProvider#handleElementContentChanged(org.eclipse.ui.IFileEditorInput)
	 * @custom
	 */
	protected void handleElementContentChanged(IFileEditorInput fileEditorInput) {

		FileInfo info= (FileInfo) getElementInfo(fileEditorInput);
		if (info == null)
			return;

		IDocument document= createEmptyDocument();
		IStatus status= null;

		try {

			try {
				refreshFile(fileEditorInput.getFile());
			} catch (CoreException x) {
				handleCoreException(x, "File Changed outside");
			}

			setDocumentContent(document, fileEditorInput);

		} catch (CoreException x) {
			status= x.getStatus();
		}

		Object newContent= document.getContent();

		if ( !newContent.equals(info.fDocument.getContent())) {

			// set the new content and fire content related events
			fireElementContentAboutToBeReplaced(fileEditorInput);

			removeUnchangedElementListeners(fileEditorInput, info);

			info.fDocument.removeDocumentListener(info);
			info.fDocument.setContent(newContent);
			info.fCanBeSaved= false;
			info.fModificationStamp= computeModificationStamp(fileEditorInput.getFile());
			info.fStatus= status;

			addUnchangedElementListeners(fileEditorInput, info);

			fireElementContentReplaced(fileEditorInput);

		} 
	}
	protected void handleElementMoved(IFileEditorInput fileEditorInput, IPath path) {
		super.handleElementMoved(fileEditorInput, path);
	}
	/*
	 * (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide.document.FileDiagramDocumentProvider#createInputWithEditingDomain(org.eclipse.ui.IEditorInput, org.eclipse.emf.transaction.TransactionalEditingDomain)
	 * @custom
	 */
	public IEditorInput createInputWithEditingDomain(IEditorInput editorInput, TransactionalEditingDomain domain) {
		if(editorInput instanceof IDiagramFileEditorInputProxy){
			((IDiagramFileEditorInputProxy)editorInput).setTransactionalEditingDomain(domain);
			return editorInput;
		}else{
			return super.createInputWithEditingDomain(editorInput, domain);
		}
	}
	/**
	 * @author Shashidhar Kannoori
	 * @custom
	 */
	public class DiagramFileInfoSync extends DiagramFileInfo{

		ISaveEventDispatcher dispatcher;
		IFileEditorInput input;
		public boolean refreshedByShared = false;
		public DiagramFileInfoSync(IDocument document, FileSynchronizer fileSynchronizer, DiagramModificationListener listener,
				IFileEditorInput input) {
			super(document, fileSynchronizer, listener);
			final IDocument inUseDocument = document;
			final DiagramFileEditorInputProxy inputProxy =(DiagramFileEditorInputProxy)input;
			if(dispatcher == null){
				dispatcher = new SaveEventDispatcher(){
					public void updateTimeStamp(ISaveInfo info) {
						fModificationStamp = info.getTimeStamp();
//						Object object = info.getSource();
//						
//						if(object instanceof ElementInfo){
//							
//							if(inUseDocument.equals(((ElementInfo)object).fDocument)){
//								return;
//							}
//						}
//						MergeOperation operation = new MergeOperation(inputProxy.getEditingDomain(),
//								"Document Merge Operation", (ElementInfo)object, inUseDocument);
//						try{
//							operation.execute(new NullProgressMonitor(), null );
//						}catch(ExecutionException exception){
//							exception.printStackTrace();
//						}
					}
				};
				if(dispatcher != null){
					DiagramService.eInstance().addDispatchers(dispatcher);
				}
			}
			this.input = input;
			
		}
		public void updateTimeStamp(){
			long timestamp = getModificationStamp(input);
			SaveInfo info = DiagramService.eInstance().getSaveInfo(this, timestamp);
			refreshedByShared = true;
			DiagramService.eInstance().dispatch(info);
			refreshedByShared = false;
		}
		public void updateTimeStamp(IFile file){
			long timestamp = computeModificationStamp(file);
			SaveInfo info = DiagramService.eInstance().getSaveInfo(this, timestamp);
			DiagramService.eInstance().dispatch(info);
		}

		
		public void disposeDispatcher(){
			if(dispatcher !=null)
				DiagramService.eInstance().removeDispatchers(dispatcher);
		}
	}
	/*
	 * (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide.document.FileDiagramDocumentProvider#doSaveDocument(org.eclipse.core.runtime.IProgressMonitor, java.lang.Object, org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDocument, boolean)
	 * @custom
	 */
	protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException {
		if (element instanceof IFileEditorInput) {

			IFileEditorInput input= (IFileEditorInput) element;
			FileInfo info= (FileInfo) getElementInfo(element);
			IFile file= input.getFile();

			if (file.exists()) {

				if (info != null && !overwrite)
					checkSynchronizationState(info.fModificationStamp, file);

				// inform about the upcoming content change
				fireElementStateChanging(element);
				try {
					System.out.println("Time timestamp before saving: " + computeModificationStamp(file));
					saveDocumentToFile(document, file, overwrite, monitor);
					// Dispatch the save event.
					if(info instanceof DiagramFileInfoSync){
						((DiagramFileInfoSync)info).updateTimeStamp();
					}
					System.out.println("Time timestamp after saving: " + computeModificationStamp(file));
					
				} 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) {
					info.fModificationStamp= computeModificationStamp(file);
				}

			} else {
				try {
					monitor.beginTask(DiagrammingResources.FileDocumentProvider_task_saving, 3000);
					ContainerCreator creator = new ContainerCreator(file.getWorkspace(), file.getParent().getFullPath());
					creator.createContainer(new SubProgressMonitor(monitor, 1000));
					file.create(new ByteArrayInputStream("".getBytes()), false, new SubProgressMonitor(monitor, 1000)); //$NON-NLS-1$
					saveDocumentToFile(document, file, overwrite, new SubProgressMonitor(monitor, 1000));
				}
				finally {
					monitor.done();
				}
			}
		} else {
			super.doSaveDocument(monitor, element, document, overwrite);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide.document.FileDiagramDocumentProvider#disposeElementInfo(java.lang.Object, org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.AbstractDocumentProvider.ElementInfo)
	 * @custom
	 */
	protected void disposeElementInfo(Object element, ElementInfo info) {
		if(info instanceof DiagramFileInfoSync){
			((DiagramFileInfoSync)info).disposeDispatcher();
		}
		super.disposeElementInfo(element, info);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.editor.AbstractDocumentProvider#createElementInfo(java.lang.Object)
	 */
	protected ElementInfo createElementInfo(Object element) throws CoreException {
		if (element instanceof IFileEditorInput) {

			IFileEditorInput input= (IFileEditorInput) element;

			try {
				refreshFile(input.getFile());
			} catch (CoreException x) {
				handleCoreException(x, DiagrammingResources.FileDocumentProvider_createElementInfo);
			}

			IDocument d= null;
			IStatus s= null;

			try {
				d= createDocument(element);
			} catch (CoreException x) {
				handleCoreException(x, DiagrammingResources.FileDocumentProvider_createElementInfo);
				s= x.getStatus();
				d= createEmptyDocument();
			}
			
			DiagramFileSynchronizer f= new DiagramFileSynchronizer(input);
			f.install();

			FileInfo info= createFileInfo(d, f, input);
			info.fModificationStamp= computeModificationStamp(input.getFile());
			info.fStatus= s;

			return info;
		}

		return super.createElementInfo(element);
	}
	
	/**
	 * Does merge operation of the resource if resource contents are saved by shared
	 * IDocument. 
	 * @author Shashidhar Kannoori
	 */
	public class MergeOperation extends AbstractEMFOperation{

		private ElementInfo elementInfo;
		private IDocument toMergeDocument;

		public MergeOperation(TransactionalEditingDomain domain, String label,
				ElementInfo elementInfo, IDocument toMergeDocument) {
			super(domain, label);
			this.elementInfo = elementInfo;
			this.toMergeDocument = toMergeDocument;
		}

		protected IStatus doExecute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
			try{
			if(elementInfo instanceof ElementInfo){
				IDocument savedDocument = ((ElementInfo)elementInfo).fDocument;
				Diagram saveddiagram  = (Diagram)savedDocument.getContent();
				if(saveddiagram != null){
					Diagram inUseDiagram = (Diagram)toMergeDocument.getContent();
					GMFResource gmfResource = (GMFResource)inUseDiagram.eResource();
					EList list = gmfResource.getContents();

					String guid = UmaUmlUtil.getUmaGuidFromUmlElement((NamedElement)saveddiagram.getElement());
					Diagram replacingDiagram = null;
					List newList = new ArrayList();
					for (Iterator iter = list.iterator(); iter.hasNext();) {
						EObject element = (EObject) iter.next();
						if(element instanceof Activity){
							String currentguid = UmaUmlUtil.getUmaGuidFromUmlElement((NamedElement)element);
							if(currentguid.equals(guid)){
								newList.add(saveddiagram.getElement());
							}else{
								newList.add(element);
							}
						}
						if(element instanceof Diagram){
							Diagram diagram = (Diagram)element;
							EObject object = ((Diagram)element).getElement();
							String rGuid = UmaUmlUtil.getUmaGuidFromUmlElement((NamedElement)object);
							if(guid.equals(rGuid)){
								replacingDiagram = diagram;
								newList.add(saveddiagram);
							}else{
								newList.add(element);
							}
						}
					}
					
					if(replacingDiagram == null){
						newList.add(saveddiagram.getElement());
						newList.add(saveddiagram);
					}
					//Transaction tx = create 
					// TODO handle better way to merge the elements.
					if(!newList.isEmpty()){
						boolean notification = gmfResource.eDeliver();
						gmfResource.eSetDeliver(false);
						gmfResource.getContents().clear();
						gmfResource.getContents().addAll(newList);
						gmfResource.eSetDeliver(notification);
						//list.addAll(newList);
					}
				}
			}
			}catch(Exception e){
				System.out.println("Warning: Document merge failed due to "+ e.getMessage());
				return Status.CANCEL_STATUS;
			}
			return Status.OK_STATUS;
		}
	}
	
	   
    /**
     * Handles the saving of the diagram to a file
     * 
     * @param domain
     *            the TransactionalEditingDomain we are saving in
     * @param file
     *            the IFile to save to
     * @param diagram
     *            Diagram that will be saved
     * @param options
     *            save options or null
     * @param monitor
     *            IProgressMonitor
     * @throws CoreException
     */
    protected void doSave(TransactionalEditingDomain domain, IFile file,
            Diagram diagram, Map options, IProgressMonitor monitor)
        throws CoreException {
        if (options == null) {
            DiagramPersister.save(domain, file, diagram, DiagramPersister
                .hasUnrecognizedData(diagram.eResource()), monitor);
        } else {
        	DiagramPersister.save(domain, file, diagram, monitor, options);
        }
    }
    
    /**
	 * Synchronizes the document with external resource changes.
	 */
	protected class DiagramFileSynchronizer extends FileSynchronizer {

		/**
		 * Creates a new file synchronizer. Is not yet installed on a resource.
		 *
		 * @param fileEditorInput the editor input to be synchronized
		 */
		public DiagramFileSynchronizer(IFileEditorInput fileEditorInput) {
			super(fileEditorInput);
		}
		/*
		 * @see IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
		 */
		public boolean visit(IResourceDelta delta) throws CoreException {
			if (delta == null)
				return false;

			delta= delta.findMember(getFile().getFullPath());

			if (delta == null)
				return false;

			Runnable runnable= null;

			switch (delta.getKind()) {
				case IResourceDelta.CHANGED:
					DiagramFileInfoSync info= (DiagramFileInfoSync) getElementInfo(fFileEditorInput);
					if (info == null || info.fCanBeSaved)
						break;

					boolean isSynchronized= computeModificationStamp(getFile()) == info.fModificationStamp;
					if (((IResourceDelta.ENCODING & delta.getFlags()) != 0 && isSynchronized) || ((IResourceDelta.CONTENT & delta.getFlags()) != 0 && !isSynchronized)
							|| info.refreshedByShared) {
						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 {
						info= (DiagramFileInfoSync) getElementInfo(fFileEditorInput);
						if (info != null && !info.fCanBeSaved) {
							runnable= new SafeChange(fFileEditorInput) {
								protected void execute(IFileEditorInput input) throws Exception {
									handleElementDeleted(input);
								}
							};
						}
					}
					break;
			}

			if (runnable != null)
				update(runnable);

			return false;
		}
	}	
	
	public void unsetCanSaveDocument(Object element) {
		if (element != null) {
			ElementInfo info = (ElementInfo) getElementInfo(element);
			if (info != null) {
				removeUnchangedElementListeners(element, info);
				info.fCanBeSaved = false;
				addUnchangedElementListeners(element, info);
				fireElementDirtyStateChanged(element, info.fCanBeSaved);
			}
		}
	}
}
