//------------------------------------------------------------------------------
// 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.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.ecore.xmi.XMLHelper;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.XMISaveImpl;
import org.eclipse.epf.common.serviceability.EPFVersions;
import org.eclipse.epf.common.serviceability.VersionUtil;
import org.eclipse.epf.resourcemanager.ResourceManager;
import org.eclipse.epf.uma.MethodElement;

/**
 * XMLSave implementation for library XMI persistence
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class MultiFileXMISaveImpl extends XMISaveImpl {

	public static final String SAVE_SEPARATELY_CLASS_SET = "SAVE_SEPARATELY_CLASS_SET"; //$NON-NLS-1$

	/**
	 * Save options to force saving all resources in the resource set, whether
	 * they have been modified or unchanged. Its value must be a string "true"
	 * or "false"
	 */
	public static final String SAVE_ALL = "SAVE_ALL"; //$NON-NLS-1$

	/**
	 * Save option to save objects of the save type together in the same file if
	 * MultiFileUtil.createFileURI() returns the same URI for them.
	 */
	public static final String SAVE_TOGETHER_CLASS_SET = "SAVE_TOGETHER_CLASS_SET"; //$NON-NLS-1$

	public static final String BACK_UP_BEFORE_SAVE = "BACK_UP_BEFORE_SAVE"; //$NON-NLS-1$

	public static final String DISCARD_UNRESOLVED_REFERENCES = "DISCARD_UNRESOLVED_REFERENCES"; //$NON-NLS-1$

	static final String MODIFIED_RESOURCE_SET = "MODIFIED_RESOURCE_SET"; //$NON-NLS-1$

	/**
	 * Save option to specify a TxRecord to log the transactional data for
	 * fail-safe persistence
	 * 
	 * @see org.eclipse.epf.uma.util.IFileBasedLibraryPersister.FailSafeMethodLibraryPersister
	 * @see TxRecord
	 */
	static final String TX_RECORD = "TX_RECORD"; //$NON-NLS-1$

	public static final String MULTI_FILE = "MULTI_FILE"; //$NON-NLS-1$

	/**
	 * Save option to refresh the workspace when new resource is created and
	 * saved. Its value must be a string "true" or "false"
	 */
	public static final String REFRESH_NEW_RESOURCE = "REFRESH_NEW_RESOURCE"; //$NON-NLS-1$

	/**
	 * Save option to check the resource for modifiable before saving it. Its
	 * value must be a string "true" or "false"
	 */
	public static final String CHECK_MODIFY = "CHECK_MODIFY"; //$NON-NLS-1$

	// private Resource resource;
	private Set saveSeparatelyClassSet;

	private Map options;

	/**
	 * @param helper
	 */
	public MultiFileXMISaveImpl(XMLHelper helper) {
		super(helper);
	}

	XMLHelper getXMLHelper() {
		return helper;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl#init(org.eclipse.emf.ecore.xmi.XMLResource,
	 *      java.util.Map)
	 */
	protected void init(XMLResource resource, Map opts) {
		super.init(resource, opts);

		if (escape != null) {
			// use MyEscape to ignore whitespaces
			//
			escape = new MyEscape();
		}

		saveSeparatelyClassSet = (Set) opts.get(SAVE_SEPARATELY_CLASS_SET);
		options = opts;

		ResourceSet resourceSet = resource.getResourceSet();
		if (resourceSet == null) {
			resourceSet = new MultiFileResourceSetImpl();
			resourceSet.getResources().add(resource);
		}
	}

	boolean canSaveSeparately(Object obj) {
		return MultiFileSaveUtil.hasOwnResource(obj, saveSeparatelyClassSet);
	}

	private String getUmaHREF(Resource resource, InternalEObject o) {
		if (o.eIsProxy()
				&& o.eProxyURI().scheme().equals(MultiFileURIConverter.SCHEME)) {
			return o.eProxyURI().toString();
		}
		String href = null;
		if (o instanceof MethodElement) {
			href = helper.getHREF(o);
		}
		if (href == null) {
			PersistencePlugin.getDefault().getLogger().logError("Could not find resource descriptor for resource " + resource + "\n  object: " + o); //$NON-NLS-1$ //$NON-NLS-2$
			return MultiFileSaveUtil.getHREF(resource, o);
		}
		return href;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl#saveHref(org.eclipse.emf.ecore.EObject,
	 *      org.eclipse.emf.ecore.EStructuralFeature)
	 */
	protected void saveHref(EObject remote, EStructuralFeature f) {
		if (f instanceof EReference && ((EReference) f).isContainment()
				&& !toDOM) {
			// if this HREF is a contained element, save its ID attribute so the
			// proxy can be cached in the
			// GUIDToElementMap for temporary use before it can be resolved.
			// This helps improve loading time.
			//
			String href = helper.getHREF(remote);
			if (href != null) {
				if (escapeURI != null) {
					href = escapeURI.convert(href);
				}
				String name = helper.getQName(f);
				doc.startElement(name);
				EClass eClass = remote.eClass();
				EClass expectedType = (EClass) f.getEType();
				if (saveTypeInfo ? xmlTypeInfo.shouldSaveType(eClass,
						expectedType, f) : eClass != expectedType
						&& expectedType.isAbstract()) {
					saveTypeAttribute(eClass);
				}
				String id = helper.getID(remote);
				if (id != null) {
					doc.addAttribute(idAttributeName, id);
				}
				doc.addAttribute(XMLResource.HREF, href);
				if (eObjectToExtensionMap != null) {
					processAttributeExtensions(remote);
					if (processElementExtensions(remote)) {
						doc.endElement();
					} else {
						doc.endEmptyElement();
					}
				} else {
					doc.endEmptyElement();
				}
			}
			return;
		}

		super.saveHref(remote, f);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl#saveFeatures(org.eclipse.emf.ecore.EObject)
	 */
	protected boolean saveFeatures(EObject o) {
		try {
			MultiFileXMIResourceImpl resource = (MultiFileXMIResourceImpl) o
					.eResource();
			if (resource != null) {
				EObject container = o.eContainer();
				InternalEObject internalEObject = ((InternalEObject) o);
				if (o instanceof MethodElement && canSaveSeparately(o)
						&& container != null) {
					boolean containsNewFeature = (resource == container
							.eResource());
					MethodElement e = (MethodElement) o;
					URI uri = MultiFileSaveUtil
							.createFileURI((MethodElement) o);
					if (containsNewFeature) {
						if (!internalEObject.eIsProxy()) {
							resource = (MultiFileXMIResourceImpl) MultiFileSaveUtil
									.save(o, uri, options);
						}
					} else {
						// check if there is a ResourceDescriptor for this
						// element
						// create a new one if needed
						//
						ResourceManager resMgr = MultiFileSaveUtil
								.getResourceManager(container.eResource());
						if (resMgr != null
								&& resMgr.getResourceDescriptor(e.getGuid()) == null) {
							// make sure that no other ResourceManager has a
							// ResourceDescriptor for this element
							//
							MultiFileURIConverter uriConverter = (MultiFileURIConverter) resource
									.getResourceSet().getURIConverter();
							if (uriConverter
									.findResourceDescriptor(e.getGuid()) == null) {
								MultiFileSaveUtil.registerWithResourceManager(
										resMgr, e, resource.getFinalURI());
							}
						}
					}

					String href = getUmaHREF(resource, internalEObject);
					doc.addAttribute(XMLResource.HREF, href);
					endSaveFeatures(o, 0, null);
					return true;
				}
				if (o instanceof ResourceManager
						&& helper.getResource() != resource) {
					String href = getUmaHREF(resource, internalEObject);
					doc.addAttribute(XMLResource.HREF, href);
					endSaveFeatures(o, 0, null);
					return true;
				}
			}
			return super.saveFeatures(o);
		} catch (RuntimeException e) {
			CommonPlugin.INSTANCE.log(e);
			if (MultiFileSaveUtil.DEBUG) {
				e.printStackTrace();
				System.err.println("ERROR saving feature: " + o); //$NON-NLS-1$
				System.err.println("  Feature resource: " + o.eResource()); //$NON-NLS-1$
			}
			throw e;
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.emf.ecore.xmi.impl.XMISaveImpl#addNamespaceDeclarations()
	 */
	public void addNamespaceDeclarations() {
		super.addNamespaceDeclarations();
		
		if (!toDOM) {
			// save tool version info
			//
			for (Iterator iter = VersionUtil.getAllToolIDs().iterator();iter.hasNext();) {
				String toolID = (String)iter.next();
				EPFVersions epfVersions = VersionUtil.getVersions(toolID);
				String nsUri = epfVersions.getNsURI();
				doc.addAttribute(ExtendedMetaData.XMLNS_PREFIX + ":" + toolID, nsUri); //$NON-NLS-1$
				String toolVersion = epfVersions.getMinToolVersionForCurrentLibraryVersion().getToolVersion().toString();
				doc.addAttribute(toolID + ":version", toolVersion); //$NON-NLS-1$
			}
		}
	}

	/*
	 * protected String getDatatypeValue(Object value, EStructuralFeature f,
	 * boolean isAttribute) { if (value != null && value instanceof String) {
	 * String str = (String)value; if (str.indexOf("\r") > 0) { str =
	 * str.replaceAll("\r", ""); return super.getDatatypeValue(str, f,
	 * isAttribute); } }; return super.getDatatypeValue(value, f, isAttribute); }
	 */

	// TODO: needs to revisit this class since its base class has been updated a
	// lot in EMF 2.2
	public static class MyEscape extends Escape {
		protected final char[] GREATER = { '&', 'g', 't', ';' };

		protected final char[] BLANK = {};

		public MyEscape() {
			super();
		}

		/*
		 * Converts: & to &amp; < to &lt; " to &quot; \t to &#x9; \n to &#xA; \r
		 * to &#xD;
		 */
		public String convert(String input) {
			boolean changed = false;
			int inputLength = input.length();
			grow(inputLength);
			input.getChars(0, inputLength, value, 0);
			int pos = 0;
			char ch = 0;
			while (inputLength-- > 0) {
				ch = value[pos];
				switch (ch) {
				case '&':
					pos = replace(pos, AMP, inputLength);
					changed = true;
					break;
				case '<':
					pos = replace(pos, LESS, inputLength);
					changed = true;
					break;
				case '>':
					pos = replace(pos, GREATER, inputLength);
					changed = true;
					break;
				case '"':
					pos = replace(pos, QUOTE, inputLength);
					changed = true;
					break;
				default:
					/*
					 * if (!XMLChar.isValid(ch)) { throw new
					 * RuntimeException("An invalid XML character (Unicode: 0x" +
					 * Integer.toHexString(ch)+") was found in the element
					 * content:" +input); }
					 */
					pos++;
					break;
				}
			}
			return changed ? new String(value, 0, pos) : input;
		}

		/**
		 * Converts: & to &amp; < to &lt; > to &gt; " to &quot; \n to
		 * platform-dependent line breaking character
		 */
		public String convertText(String input) {
			boolean changed = false;
			int inputLength = input.length();
			grow(inputLength);
			input.getChars(0, inputLength, value, 0);
			int pos = 0;
			while (inputLength-- > 0) {
				switch (value[pos]) {
				case '&':
					pos = replace(pos, AMP, inputLength);
					changed = true;
					break;
				case '<':
					pos = replace(pos, LESS, inputLength);
					changed = true;
					break;
				case '>':
					pos = replace(pos, GREATER, inputLength);
					changed = true;
					break;
				case '"':
					pos = replace(pos, QUOTE, inputLength);
					changed = true;
					break;
				case '\r':
					pos = replace(pos, BLANK, inputLength);
					changed = true;
					break;
				case '\n':
					pos = replace(pos, LINE_FEED, inputLength);
					changed = true;
					break;
				default:
					pos++;
					break;
				}
			}
			return changed ? new String(value, 0, pos) : input;
		}

		/*
		 * Taken from XMLSaveImpl$Escape.convertText, and added conversion of >
		 * This is used for XLIFF's - change it's name so it doesn't impact EMF
		 * saving Convert: & to &amp; < to &lt; " to &quot; \n to line separator
		 */
		public String myConvertText(String input) {
			boolean changed = false;
			int inputLength = input.length();
			grow(inputLength);
			input.getChars(0, inputLength, value, 0);
			int pos = 0;
			while (inputLength-- > 0) {
				switch (value[pos]) {
				case '&':
					pos = replace(pos, AMP, inputLength);
					changed = true;
					break;
				case '<':
					pos = replace(pos, LESS, inputLength);
					changed = true;
					break;
				case '>':
					pos = replace(pos, GREATER, inputLength);
					changed = true;
					break;
				case '"':
					pos = replace(pos, QUOTE, inputLength);
					changed = true;
					break;
				case '\n': {
					pos = replace(pos, LINE_FEED, inputLength);
					changed = true;
					break;
				}
				default:
					pos++;
					break;
				}
			}

			return changed ? new String(value, 0, pos) : input;
		}
	}

	public static boolean checkModifyRequired(Map options) {
		Object opt = options.get(MultiFileXMISaveImpl.CHECK_MODIFY);
		return opt != null ? Boolean.valueOf(opt.toString()).booleanValue()
				: false;
	}
}