//------------------------------------------------------------------------------
// 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
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// 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.diagram.core.providers;

import java.util.Iterator;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
import org.eclipse.epf.common.CommonPlugin;
import org.eclipse.epf.common.ui.util.MsgBox;
import org.eclipse.epf.diagram.core.DiagramCorePlugin;
import org.eclipse.epf.diagram.core.part.DiagramEditorInputProxy;
import org.eclipse.epf.diagram.core.part.IDiagramFileEditorInputProxy;
import org.eclipse.epf.diagram.core.part.util.DiagramEditorUtil;
import org.eclipse.epf.diagram.core.services.DiagramManager;
import org.eclipse.epf.diagram.core.services.FileSynchronizer;
import org.eclipse.epf.diagram.model.util.TxUtil;
import org.eclipse.epf.services.Services;
import org.eclipse.epf.services.ILibraryPersister.FailSafeMethodLibraryPersister;
import org.eclipse.epf.uma.Activity;
import org.eclipse.gmf.runtime.common.core.util.Log;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.DiagramDocument;
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.diagram.ui.resources.editor.ide.document.StorageDiagramDocumentProvider;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide.document.WorkspaceOperationRunner;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide.internal.EditorIDEPlugin;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide.internal.l10n.EditorMessages;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.internal.EditorPlugin;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.internal.EditorStatusCodes;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IStorageEditorInput;

/**
 * @author Phong Nguyen Le
 *
 * @since 1.2
 */
public class SharedResourceDiagramDocumentProvider extends StorageDiagramDocumentProvider 
{
	private static class FileDiagramDocumentProviderEx extends FileDiagramDocumentProvider {
		@Override
		protected ISchedulingRule getSaveRule(Object element) {
			if (element instanceof IFileEditorInput) {
				IFileEditorInput input= (IFileEditorInput) element;
				return computeSaveSchedulingRule(input.getFile());
			}
			return null;
		}
		
		/**
		 * Computes the scheduling rule needed to create or modify a resource. If
		 * the resource exists, its modify rule is returned. If it does not, the
		 * resource hierarchy is iterated towards the workspace root to find the
		 * first parent of <code>toCreateOrModify</code> that exists. Then the
		 * 'create' rule for the last non-existing resource is returned.
		 *
		 * @param toCreateOrModify the resource to create or modify
		 * @return the minimal scheduling rule needed to modify or create a resource
		 */
		private ISchedulingRule computeSaveSchedulingRule(IResource toCreateOrModify) {
			if (toCreateOrModify.exists() && toCreateOrModify.isSynchronized(IResource.DEPTH_ZERO))
				return fResourceRuleFactory.refreshRule(toCreateOrModify);

			IResource parent= toCreateOrModify;
			do {
				 /*
				 * XXX This is a workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=67601
				 * IResourceRuleFactory.createRule should iterate the hierarchy itself.
				 */
				toCreateOrModify= parent;
				parent= toCreateOrModify.getParent();
			} while (parent != null && !parent.exists() && !parent.isSynchronized(IResource.DEPTH_ZERO));

			return fResourceRuleFactory.createRule(toCreateOrModify);
		}
		
		@Override
		protected IRunnableContext getOperationRunner(IProgressMonitor monitor) {
			return super.getOperationRunner(monitor);
		}
	}
	
	private static final FileDiagramDocumentProviderEx fileDiagramDocumentProvider = new FileDiagramDocumentProviderEx();
	
	//a StorageInfo with a DiagramModificationListener 
	private class DiagramStorageInfo extends StorageInfo {

		DiagramModificationListener fListener;
		public DiagramStorageInfo(IDocument document, DiagramModificationListener listener) {
			super(document);
			fListener = listener;
		}
		
	}

	private WorkspaceOperationRunner fOperationRunner;
	private DiagramManager fDiagramMgr;
	private boolean locked = false;

	public SharedResourceDiagramDocumentProvider(DiagramManager diagramMgr) {
		super();
		fDiagramMgr = diagramMgr;
	}
	
	@Override
	protected boolean setDocumentContent(IDocument document, IEditorInput editorInput) throws CoreException {
		if(document instanceof IDiagramDocument) {
			((IDiagramDocument)document).setEditingDomain(fDiagramMgr.getEditingDomain());
		}
		return super.setDocumentContent(document, editorInput);
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide.document.StorageDiagramDocumentProvider#setDocumentContentFromStorage(org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDocument, org.eclipse.core.resources.IStorage)
	 */
	protected void setDocumentContentFromStorage(IDocument document, IStorage storage) 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, EditorIDEPlugin.getPluginId(), EditorStatusCodes.ERROR, EditorMessages.FileDocumentProvider_handleElementContentChanged, null));
				}
			}
		}
		document.setContent(((org.eclipse.epf.diagram.core.resources.IDiagramStorage)storage).getDiagram());
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide.document.StorageDiagramDocumentProvider#disposeElementInfo(java.lang.Object, org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.AbstractDocumentProvider.ElementInfo)
	 */
	@Override
	protected void disposeElementInfo(Object element, ElementInfo info) {
		((DiagramStorageInfo)info).fListener.stopListening();
	}

	@Override
	protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException {
		final Diagram diagram = (Diagram) document.getContent();
		//TODO: handle case where user did not refresh diagram after diagram's resource has been reloaded
		// diagram does not have a resource in this case
		// if overwrite allowed, this diagram should replace the diagram in the reloaded resource.
		//
		Resource resource = diagram.eResource();
		if (!overwrite) {
			DiagramManager.checkSynchronizationState(resource);
		}		
		IStatus status = Services.getAccessController().checkModify(new Resource[] {resource}, MsgBox.getDefaultShell());
		if(!status.isOK()) {
			throw new CoreException(status);
		}
		
		// inform about the upcoming content change
		fireElementStateChanging(element);
		
		if(diagram.getElement() instanceof org.eclipse.epf.diagram.model.Diagram) {
			try {
				TxUtil.runInTransaction(diagram, new Runnable() {

					public void run() {
						diagram.persistChildren();
						for (Object child : diagram.getChildren()) {
							((View) child).persistChildren();
						}
					}
					
				});
			} catch (ExecutionException e) {
				DiagramCorePlugin.getDefault().getLogger().logError(e);
			}
		}
		
		FailSafeMethodLibraryPersister persister = Services.getLibraryPersister(Services.XMI_PERSISTENCE_TYPE).getFailSafePersister();
		try {
//			resource.save(Collections.EMPTY_MAP);
			persister.save(resource);
			persister.commit();
		} catch (Exception e) {
			CommonPlugin.getDefault().getLogger().logError(e);
			
			persister.rollback();
			
			// inform about failure
			fireElementStateChangeFailed(element);
			throw new CoreException(new Status(IStatus.ERROR, DiagramCorePlugin.PLUGIN_ID
					, EditorStatusCodes.RESOURCE_FAILURE, e
					.getLocalizedMessage(), null));
		}
		
		try {
			fDiagramMgr.removeDiagramBackup(getActivity((IEditorInput) element), diagram.getType());
			if(DiagramManager.ADD_kind.equals(diagram.getType())
					|| DiagramManager.WPD_kind.equals(diagram.getType())) {
				org.eclipse.epf.diagram.model.Diagram d = (org.eclipse.epf.diagram.model.Diagram) diagram.getElement();
				d.setNew(false);
			}
		} catch (RuntimeException x) {
			// inform about failure
			fireElementStateChangeFailed(element);
			throw x;
		}
		
		if(monitor != null) {
			monitor.done();
		}
		
		logResourceErrorsAndWarnings(resource);
	}
	
	private static void logResourceErrorsAndWarnings(Resource resource) {
		for (Iterator iter = resource.getErrors().iterator(); iter.hasNext();) {
			Resource.Diagnostic diagnostic = (Resource.Diagnostic) iter.next();
			Log.error(EditorPlugin.getInstance(), EditorStatusCodes.ERROR, diagnostic.getMessage());				
		}

		for (Iterator iter = resource.getWarnings().iterator(); iter.hasNext();) {
			Resource.Diagnostic diagnostic = (Resource.Diagnostic) iter.next();
			Log.warning(EditorPlugin.getInstance(), EditorStatusCodes.WARNING, diagnostic.getMessage());				
		}
	}

	@Override
	public long getModificationStamp(Object element) {
		if (element instanceof IFileEditorInput) {
			IFileEditorInput input= (IFileEditorInput) element;
			return FileSynchronizer.computeModificationStamp(input.getFile());
		}

		return super.getModificationStamp(element);
	}
	
	public void setContent(IEditorInput input) {
		ElementInfo info = getElementInfo(input);
		if (info == null)
			return;

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

		try {
			setDocumentContent(document, input);
		} catch (CoreException x) {
			status = x.getStatus();
		}
		
		Object newContent= document.getContent();
		
		// set the new content and fire content related events
		fireElementContentAboutToBeReplaced(input);

		removeUnchangedElementListeners(input, info);

		info.fDocument.removeDocumentListener(info);
		info.fDocument.setContent(newContent);
		info.fCanBeSaved = false;
		info.fStatus = status;

		addUnchangedElementListeners(input, info);

		fireElementContentReplaced(input);
	}
		
	/**
	 * Updates the element info to a change of the file content and sends out
	 * appropriate notifications.
	 *
	 * @param input the input of a document editor
	 */
	public void handleElementContentChanged(IEditorInput input) {
		ElementInfo info = getElementInfo(input);
		if (info == null)
			return;

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

		try {
			setDocumentContent(document, input);
		} 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(input);

			removeUnchangedElementListeners(input, info);

			info.fDocument.removeDocumentListener(info);
			info.fDocument.setContent(newContent);
			info.fCanBeSaved= false;
			info.fStatus= status;

			addUnchangedElementListeners(input, info);

			fireElementContentReplaced(input);

		} else {
			
			handleExistingDocumentSaved(input, info, status);

		}
	}

	private void handleExistingDocumentSaved(IEditorInput input, ElementInfo info, IStatus status) {
		removeUnchangedElementListeners(input, info);

		// fires only the dirty state related event
		info.fCanBeSaved= false;
		info.fStatus= status;

		addUnchangedElementListeners(input, info);

		fireElementDirtyStateChanged(input, false);		
	}

	public void markDocumentAsSaved(IFileEditorInput input) {
		ElementInfo info = getElementInfo(input);
		if (info == null)
			return;
		handleExistingDocumentSaved(input, info, null);
	}
	
	@Override
	protected void doSynchronize(Object element, IProgressMonitor monitor) throws CoreException {
		if(element instanceof IEditorInput) {
			handleElementContentChanged((IEditorInput) element);
			return;
		}
		super.doSynchronize(element, monitor);
	}
	
	@Override
	public boolean isSynchronized(Object element) {
		ElementInfo info = getElementInfo(element);
		if(info.fDocument instanceof IDiagramDocument) {
			Diagram diagram = ((IDiagramDocument)info.fDocument).getDiagram();
			if(diagram != null) {
				Resource resource = diagram.eResource();
				// a diagram that does not have a resource is considered as out-of-synch
				// because its resource must have been reloaded.
				//
				return resource != null && DiagramManager.isSynchronized(resource);
			}
		}
		return super.isSynchronized(element);
	}

	@Override
	public ElementInfo createNewElementInfo(IDocument document) {
		DiagramModificationListener listener = new AccessibleDiagramModificationListener(this, (DiagramDocument)document);
		DiagramStorageInfo info = new DiagramStorageInfo(document, listener);
		listener.startListening();
		return info;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.editor.AbstractDocumentProvider#getOperationRunner(org.eclipse.core.runtime.IProgressMonitor)
	 */
	protected IRunnableContext getOperationRunner(IProgressMonitor monitor) {
		return fileDiagramDocumentProvider.getOperationRunner(monitor);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.editor.AbstractDocumentProvider#getSaveRule(java.lang.Object)
	 */
	protected ISchedulingRule getSaveRule(Object element) {
		return fileDiagramDocumentProvider.getSaveRule(element);
	}

	/**
	 * Allows editing even the document is out of synch.
	 * 
	 * @param input
	 */
	public void allowEditing(IEditorInput input) {
		ElementInfo info = getElementInfo(input);
		if(info.fDocument instanceof IDiagramDocument) {
			Diagram diagram = ((IDiagramDocument)info.fDocument).getDiagram();
			if(diagram != null && diagram.eResource() == null 
					&& input instanceof IDiagramFileEditorInputProxy) {
				Activity act = getActivity(input);
				if(act != null) {
					fDiagramMgr.replaceTemporarily(act, diagram);
				}
			}
		}
	}
	
	private static Activity getActivity(IEditorInput input) {
		return (Activity) ((IDiagramFileEditorInputProxy)input).getDiagramEditorInput().getMethodElement();
	}

	public void reverseToSaved(IEditorInput input) {
		ElementInfo info = getElementInfo(input);
		if(info.fDocument instanceof IDiagramDocument) {
			Diagram diagram = ((IDiagramDocument)info.fDocument).getDiagram();
			if(diagram != null && diagram.eResource() != null 
					&& input instanceof DiagramEditorInputProxy) {
				Activity act = getActivity(input);
				if(act != null) {
					fDiagramMgr.reverseToSaved(act, diagram, ((DiagramEditorInputProxy)input).getPreferenceHint());
				}
			}
		}
	}
	
	/**
	 * If a plugin is locked, diagram editor and document provider
	 * should be locked, this is done after loading the diagram editor
	 * using this method.
	 * @param lock
	 */
	public void lock(boolean lock){
		locked =lock; 
	}
	
	@Override
	protected void updateCache(IStorageEditorInput input) throws CoreException {
		super.updateCache(input);
		StorageInfo info= (StorageInfo) getElementInfo(input);
		if (info != null) {
			if(locked && info.fIsModifiable)
				info.fIsModifiable= !locked;
		}
	}
	
	/**
	 * 
	 * returns the locked state of plugin. 
	 * locked state is  set using lock(boolean lock) method. 
	 * @return
	 */
	public boolean getLockedState(){
		return locked;
	}
	
	@Override
	public boolean isModifiable(Object element) {
		if(!DiagramEditorUtil.isModifiable(element)) {
			return false;
		}
		return super.isModifiable(element);
	}
}
