/*******************************************************************************
 * Copyright (c) 2001, 2005 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 API and implementation
 *******************************************************************************/

package org.eclipse.wst.xml.core.internal.emf2xml;


import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jem.util.emf.workbench.ProjectResourceSet;
import org.eclipse.wst.common.internal.emf.resource.EMF2DOMAdapter;
import org.eclipse.wst.common.internal.emf.resource.EMF2DOMRenderer;
import org.eclipse.wst.common.internal.emf.resource.TranslatorResource;
import org.eclipse.wst.common.internal.emf.utilities.DOMUtilities;
import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;
import org.eclipse.wst.common.internal.emfworkbench.integration.ResourceSetWorkbenchEditSynchronizer;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.model.ModelLifecycleEvent;
import org.eclipse.wst.sse.core.internal.provisional.IModelLifecycleListener;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IModelStateListener;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.xml.core.internal.Logger;
import org.eclipse.wst.xml.core.internal.document.DocumentTypeImpl;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.w3c.dom.Node;


public class EMF2DOMSSERenderer extends EMF2DOMRenderer implements IModelStateListener, IModelLifecycleListener {

	protected Object aboutToChangeNode = null;

	protected boolean isBatchChanges = false;

	private boolean isSaving = false;

	private IModelManager modelManager;

	/** The XML DOM model */
	protected IDOMModel xmlModel;

	/** Used internally; the unique id for the xml model */
	protected String xmlModelId;

	protected boolean xmlModelReverted = false;

	public EMF2DOMSSERenderer() {
		super();
	}

	public void accessForRead() {
		if (!resource.isNew()) {
			String id = getModelManagerId();
			getModelManager().getExistingModelForRead(id);
		}
	}

	public void accessForWrite() {
		modelAccessForWrite();
	}

	/**
	 * see batchModelEnd
	 * 
	 */

	public void batchModeEnd() {
		getXMLModel().changedModel();
		setRootNodeAdapterNotificationEnabled(true);
		isBatchChanges = false;
	}

	/**
	 * batchModeStart and batchModeEnd is a pair that controls notifications,
	 * and tread access. They should always be called in a try/finally block.
	 * 
	 * setBatchModel begins the processing where notifications are not sent
	 * out on each change, but saved up until the endBatchMode called.
	 * 
	 * This pair of calls can also, indirectly, "lock" the DOM Model to access
	 * from only one thread, so it should not be locked for long periods of
	 * time. That's also why it is important to have the endBatchMode in a
	 * finally block to be sure it is always called, or the DOM will be left
	 * in a locked, unusable, state and only shortly away from severere
	 * program error.
	 * 
	 * <pre><code>
	 * Example
	 * </code>
	 *  
	 *  try { 
	 *  		batchModelStart();
	 *  		...do a some work ...
	 *  		}
	 *  	finally {
	 *  		endBatchMode();
	 *  		}
	 *  
	 *  
	 * </pre>
	 */
	public void batchModeStart() {
		isBatchChanges = true;
		getXMLModel().aboutToChangeModel();
		setRootNodeAdapterNotificationEnabled(false);
	}

	private void cacheSynchronizationStamp() {
		IFile file = WorkbenchResourceHelper.getFile(resource);
		if (file != null) {
			if (xmlModel != null)
				xmlModel.resetSynchronizationStamp(file);
		}
	}

	/**
	 * Create a new Document given
	 * 
	 * @aResource.
	 */
	protected void createDocument() {
		TranslatorResource res = getResource();
		res.setDefaults();
		IFile file = WorkbenchResourceHelper.getFile(resource);
		InputStream is = DOMUtilities.createHeaderInputStream(res.getDoctype(), res.getPublicId(), res.getSystemId());
		if (is == null)
			return;
		try {
			try {
				List folders = new ArrayList();
				IContainer container = file.getParent();
				while (null != container && !container.exists() && container instanceof IFolder) {
					folders.add(container);
					container = container.getParent();
				}
				IFolder folder = null;
				for (int i = 0; i < folders.size(); i++) {
					folder = (IFolder) folders.get(i);
					folder.create(true, true, null);
				}
				file.create(is, true, null);
				file.setLocal(true, 1, null);
			}
			catch (CoreException e1) {
				Logger.logException(e1);
			}
			finally {
				if (null != is) {
					is.close();
				}
			}
			initializeXMLModel(file, true);
		}
		catch (IOException ex) {
			Logger.log(Logger.ERROR, "IWAE0017E Unexpected IO exception occurred creating xml document");//$NON-NLS-1$
		}
	}

	protected void createDOMTreeIfNecessary() {
		if (needsToCreateDOM)
			createDOMTree();
	}

	protected EMF2DOMAdapter createRootDOMAdapter() {
		return new EMF2DOMSSEAdapter(getResource(), document, this, getResource().getRootTranslator());
	}

	public void deRegisterAsModelLifecycleListener() {
		if (xmlModel != null)
			xmlModel.removeModelLifecycleListener(this);
	}

	public void deRegisterAsModelStateListener() {
		if (xmlModel != null)
			xmlModel.removeModelStateListener(this);
	}

	private void deregisterFromXMLModel() {
		deRegisterAsModelStateListener();
		deRegisterAsModelLifecycleListener();
		// This try/catch block is a hack to fix defect 204114. This occurs
		// because
		// the model manager plugin is shut down and unloaded before the j2ee
		// plugin.
		// Calling getModelManager() can result in a class cast exception that
		// should
		// be ignored.
		// ModelManager mgr = null;
		try {
			getModelManager();
		}
		catch (ClassCastException exc) {
			return;
		}
		if (xmlModel != null) {
			int writeCount = resource.getWriteCount();
			int readCount = resource.getReadCount();
			for (int i = 0; i < writeCount; i++)
				xmlModel.releaseFromEdit();
			for (int ii = 0; ii < readCount; ii++)
				xmlModel.releaseFromRead();
		}
		EMF2DOMAdapter adapter = (EMF2DOMAdapter) EcoreUtil.getAdapter(resource.eAdapters(), EMF2DOMAdapter.ADAPTER_CLASS);
		if (adapter != null) {
			adapter.removeAdapters(adapter.getNode());
		}
		xmlModel = null;
		xmlModelId = null;
	}

	public void doSave(OutputStream outputStream, Map options) throws IOException {

		try {
			isSaving = true;
			if (null != outputStream) {
				throw new RuntimeException(this.getClass().getName() + " should not use an OutputStream for saving");} //$NON-NLS-1$
			createDOMTreeIfNecessary();
			ResourceSetWorkbenchEditSynchronizer synchronizer = (ResourceSetWorkbenchEditSynchronizer) ((ProjectResourceSet) resource.getResourceSet()).getSynchronizer();
			IFile aFile = WorkbenchResourceHelper.getFile(resource);
			try {
				synchronizer.preSave(aFile);
				xmlModel.save(aFile);
			}
			catch (CoreException ex) {
				synchronizer.removeFromRecentlySavedList(aFile);
				Logger.logException(ex);
			}
			cacheSynchronizationStamp();
		}
		finally {
			isSaving = false;
		}
	}

	public EMF2DOMAdapter getExistingDOMAdapter(Node node) {
		IDOMNode xNode = (IDOMNode) node;
		return (EMF2DOMSSEAdapter) xNode.getAdapterFor(EMF2DOMAdapter.ADAPTER_CLASS);
	}

	protected IModelManager getModelManager() {
		if (modelManager == null)
			modelManager = StructuredModelManager.getModelManager();
		return modelManager;
	}

	/**
	 * Return id used to key the XML resource in the XML ModelManager.
	 */
	protected String getModelManagerId() {
		if (xmlModelId == null) {
			IFile file = WorkbenchResourceHelper.getFile(getResource());
			if (file != null) {
				xmlModelId = getModelManager().calculateId(file);
			}
			else {
				xmlModelId = resource.getURI() + Long.toString(System.currentTimeMillis());
			}
		}
		return xmlModelId;
	}

	protected ResourceSet getResourceSet() {
		return resource == null ? null : resource.getResourceSet();
	}

	/**
	 * Return the DOM model for this resource.
	 */
	public IDOMModel getXMLModel() {
		return xmlModel;
	}

	public String getXMLModelId() {
		return xmlModelId;
	}

	private IDOMModel initializeXMLModel(IFile file, boolean forWrite) throws UnsupportedEncodingException, IOException {
		if (file == null || !file.exists())
			throw new FileNotFoundException((file == null) ? "null" : file.getFullPath().toOSString()); //$NON-NLS-1$
		try {
			if (forWrite) {
				setXMLModel((IDOMModel) getModelManager().getModelForEdit(file));
			}
			else {
				setXMLModel((IDOMModel) getModelManager().getModelForRead(file));
			}
			setXMLModelId(getXMLModel().getId());
			needsToCreateDOM = false;
		}
		catch (CoreException e) {
			Logger.logException(e);
			return null;
		}
		String id = getModelManager().calculateId(file);
		syncReferenceCounts(id, forWrite);
		if (xmlModel != null)
			document = xmlModel.getDocument();
		return xmlModel;
	}

	public boolean isBatchMode() {
		return isBatchChanges;
	}

	public boolean isModified() {
		return (getXMLModel() != null && getXMLModel().isDirty());
	}

	public boolean isShared() {
		if (getResourceSet() == null || xmlModel == null)
			return false;
		return xmlModel.isShared();
	}

	public boolean isSharedForWrite() {
		if (getResourceSet() == null || xmlModel == null)
			return false;
		return xmlModel.isSharedForEdit();
	}

	protected void loadDocument(InputStream in, Map options) throws IOException {
		if (null != in) {
			throw new RuntimeException(this.getClass().getName() + " should not use an InputStream for loading");} //$NON-NLS-1$
		IFile file = WorkbenchResourceHelper.getFile(resource);
		initializeXMLModel(file, (resource.getWriteCount() != 0));
		cacheSynchronizationStamp();
	}

	protected boolean managesDOMAdapters() {
		return false;
	}

	public void modelAboutToBeChanged(IStructuredModel model) {
		if (model.getStructuredDocument() != null)
			aboutToChangeNode = model.getStructuredDocument().getFirstStructuredDocumentRegion();
	}

	public void modelAboutToBeReinitialized(IStructuredModel structuredModel) {
		// TODO Auto-generated method stub

	}

	private void modelAccessForWrite() {
		String id = getModelManagerId();
		getModelManager().getExistingModelForEdit(id);
	}

	public void modelChanged(IStructuredModel model) {
		if (isBatchChanges)
			return;
		try {
			if (aboutToChangeNode != null && model.getStructuredDocument() != null && model.getStructuredDocument().getFirstStructuredDocumentRegion() != aboutToChangeNode) {
				modelAccessForWrite();
				try {
					xmlModelReverted = true;
					resource.unload();
				}
				finally {
					if (getXMLModel() != null)
						getXMLModel().releaseFromEdit();
				}
			}
		}
		finally {
			aboutToChangeNode = null;
		}
	}

	public void modelDirtyStateChanged(IStructuredModel model, boolean isDirty) {
		if (!isDirty && resource.isModified()) { // The XMLModel was saved
			resource.setModified(false);
			long stamp = WorkbenchResourceHelper.computeModificationStamp(resource);
			WorkbenchResourceHelper.setSynhronizationStamp(resource, stamp);
			ResourceSetWorkbenchEditSynchronizer synchronizer = (ResourceSetWorkbenchEditSynchronizer) ((ProjectResourceSet) resource.getResourceSet()).getSynchronizer();
			IFile aFile = WorkbenchResourceHelper.getFile(resource);
			synchronizer.preSave(aFile);
		}
		if (isDirty)
			resource.setModified(true);
	}

	public void modelReinitialized(IStructuredModel structuredModel) {
		// TODO Auto-generated method stub

	}

	public void modelResourceDeleted(IStructuredModel model) {
		// Do nothing
	}

	public void modelResourceMoved(IStructuredModel oldModel, IStructuredModel newModel) {
		// Do nothing
	}

	/**
	 * This method is called just prior to being removed from the ResourceSet.
	 * Ensure that all reference counts to the XMLModel are removed.
	 */
	public void preDelete() {
		if (resource.isLoaded())
			deregisterFromXMLModel();
	}

	public void preUnload() {
		deregisterFromXMLModel();
	}

	public void processPostModelEvent(ModelLifecycleEvent event) {
		// TODO Auto-generated method stub

	}

	public void processPreModelEvent(ModelLifecycleEvent event) {
		if (!isSaving) {
			if (event.getType() == ModelLifecycleEvent.MODEL_SAVED) {
				ResourceSetWorkbenchEditSynchronizer synchronizer = (ResourceSetWorkbenchEditSynchronizer) ((ProjectResourceSet) resource.getResourceSet()).getSynchronizer();
				IFile aFile = WorkbenchResourceHelper.getFile(resource);
				synchronizer.preSave(aFile);
			}
		}
	}


	public void registerAsModelLifecycleListener() {
		this.xmlModel.addModelLifecycleListener(this);
	}

	/**
	 * Insert the method's description here. Creation date: (9/7/2001 10:49:53
	 * AM)
	 */
	public void registerAsModelStateListener() {
		this.xmlModel.addModelStateListener(this);
	}

	public void releaseFromRead() {
		if (xmlModel != null)
			xmlModel.releaseFromRead();
	}

	public void releaseFromWrite() {
		if (xmlModel != null)
			xmlModel.releaseFromEdit();
	}

	public void removeDOMAdapter(Node aNode, EMF2DOMAdapter anAdapter) {
		((IDOMNode) aNode).removeAdapter((EMF2DOMSSEAdapter) anAdapter);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.util.emf.xml.EMF2DOMRenderer#replaceDocumentType(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public void replaceDocumentType(String docTypeName, String publicId, String systemId) {
		if (document == null)
			return;
		DocumentTypeImpl docType = (DocumentTypeImpl) document.getDoctype();
		if (docType == null)
			return;
		if (publicId == null && systemId == null)
			document.removeChild(docType);
		else {
			docType.setPublicId(publicId);
			docType.setSystemId(systemId);
		}
	}

	/**
	 * @deprecated use batchModeStart and BatchModeEnd instead even if you do
	 *             not use batchModelStart/End, you still need to use the
	 *             try/finally pattern documented there.
	 */

	public void setBatchMode(boolean isBatch) {

		// This is some extra processing for clients to know they may be using
		// incorrectly
		if (isBatch) {
			if (isBatchChanges) {
				Logger.log(Logger.INFO_DEBUG, "setBatch was set to true when it was already true. This can be an indication of invalid calling order"); //$NON-NLS-1$
			}
		}


		if (isBatch) {
			batchModeStart();
		}
		else {
			batchModeEnd();
		}
	}

	private void setRootNodeAdapterNotificationEnabled(boolean b) {
		EObject root = resource.getRootObject();
		if (root != null) {
			EMF2DOMAdapter adapter = (EMF2DOMAdapter) EcoreUtil.getExistingAdapter(root, EMF2DOMAdapter.ADAPTER_CLASS);
			if (adapter != null) {
				adapter.setNotificationEnabled(b);
				if (b)
					adapter.updateDOM();
			}
		}
	}

	/**
	 * Return the DOM model for this resource.
	 */
	public void setXMLModel(IDOMModel xmlModel) {
		deRegisterAsModelStateListener();
		deRegisterAsModelLifecycleListener();
		this.xmlModel = xmlModel;
		registerAsModelStateListener();
		registerAsModelLifecycleListener();
	}

	public void setXMLModelId(String id) {
		xmlModelId = id;
	}

	private void syncReferenceCounts(String id, boolean forWrite) {
		int editIndex = 0, readIndex = 0;
		if (forWrite)
			editIndex++;
		else
			readIndex++;
		int writeCount = resource.getWriteCount();
		int readCount = resource.getReadCount();
		for (int i = writeCount; i > editIndex; i--)
			modelManager.getExistingModelForEdit(id);
		for (int i = readCount; i > readIndex; i--)
			modelManager.getExistingModelForRead(id);
	}

	public boolean useStreamsForIO() {
		return false;
	}

	public boolean wasReverted() {
		return xmlModelReverted;
	}
}