//------------------------------------------------------------------------------
// 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.List;

import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.UniqueEList;
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.InternalEList;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.XMIHelperImpl;
import org.eclipse.epf.resourcemanager.ResourceDescriptor;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.ecore.impl.MultiResourceEObject;

/**
 * XMLHelper implementation for library XMI persistence
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class MultiFileXMIHelperImpl extends XMIHelperImpl {

	/**
	 * Platform-specific line separator.
	 */
	private static final String LINE_SEP = System.getProperty("line.separator"); //$NON-NLS-1$

	protected boolean logError = true;

	protected List sameDocReferences;

	private boolean discardUnresolvedRef;

	/**
	 * Creates a new instance.
	 */
	public MultiFileXMIHelperImpl(MultiFileXMIResourceImpl xmiRes) {
		super(xmiRes);
		sameDocReferences = new UniqueEList();
		Boolean b = (Boolean) ((MultiFileResourceSetImpl) xmiRes
				.getResourceSet()).getDefaultSaveOptions().get(
				MultiFileXMISaveImpl.DISCARD_UNRESOLVED_REFERENCES);
		discardUnresolvedRef = b != null ? b.booleanValue() : false;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl#setResource(org.eclipse.emf.ecore.xmi.XMLResource)
	 */
	public void setResource(XMLResource resource) {
		super.setResource(resource);
		if(resource instanceof MultiFileXMIResourceImpl) {
			resourceURI = ((MultiFileXMIResourceImpl)resource).getFinalURI();
			deresolve = resourceURI != null && !resourceURI.isRelative() && resourceURI.isHierarchical();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl#getHREF(org.eclipse.emf.ecore.EObject)
	 */
	public String getHREF(EObject obj) {
		if (discardUnresolvedRef) {
			// remove unresolved references
			//
			if (obj instanceof MultiResourceEObject
					&& !((MultiResourceEObject) obj).isValid()) {
				return null;
			}
		}

		if (obj instanceof MultiResourceEObject) {
			InternalEObject o = (InternalEObject) obj;

			URI objectURI = o.eProxyURI();
			if (objectURI == null) {
				Resource otherResource = obj.eResource();
				if (otherResource == null) {
					objectURI = handleDanglingHREF(obj);
					if (objectURI == null) {
						return null;
					}
				} else if (resource == otherResource) {
					return "#" + resource.getURIFragment(obj); //$NON-NLS-1$
				} else {
					if (obj instanceof MethodConfiguration) {
						// Special handling for MethodConfiguration.
						// See
						// org.eclipse.epf.persistence.MultiFileResourceSetImpl.loadConfigurations()
						//
						EObject lib = obj.eContainer();
						if (lib != null) {
							otherResource = lib.eResource();
						} else {
							return null;
						}
					}
					if (otherResource != null) {
						ResourceSet resourceSet = otherResource.getResourceSet();
						if(resourceSet instanceof MultiFileResourceSetImpl 
								&& ((MultiFileResourceSetImpl)resourceSet).getResourceManager() == null) {
							objectURI = MultiFileSaveUtil.getFinalURI(otherResource).appendFragment(getURIFragment(otherResource, obj));
							return deresolve(objectURI).toString();
						}
						ResourceDescriptor resDesc = MultiFileSaveUtil
								.getResourceDescriptor(otherResource);
						if (resDesc != null) {
							objectURI = MultiFileURIConverter.createURI(
									resDesc.getId()).appendFragment(
									getURIFragment(otherResource, obj));
							return objectURI.toString();
						} else {
							return null;
						}
					}
				}
			} else {
				if (!objectURI.scheme().equals(MultiFileURIConverter.SCHEME)) {
					String fragment = objectURI.fragment();
					if (resource instanceof MultiFileXMIResourceImpl
							&& ((MultiFileXMIResourceImpl) resource)
									.getEObjectByID(fragment) != null) {
						return "#" + fragment; //$NON-NLS-1$
					} else {
						objectURI = deresolve(objectURI);
					}
				}
				return objectURI.toString();
			}
		}

		return super.getHREF(obj);
	}

	protected static class ProxyReference {
		private InternalEObject owner;

		private EReference reference;

		private InternalEObject proxy;

		/**
		 * @param owner
		 * @param reference
		 * @param proxy
		 */
		public ProxyReference(InternalEObject owner, EReference reference,
				InternalEObject proxy) {
			super();
			this.owner = owner;
			this.reference = reference;
			this.proxy = proxy;
		}

		public InternalEObject getOwner() {
			return owner;
		}

		public InternalEObject getProxy() {
			return proxy;
		}

		public EReference getReference() {
			return reference;
		}

	}

	public void setValue(EObject object, EStructuralFeature feature,
			Object value, int position) {
		// TODO: more efficient way to do this replacement
		// should look at MultiFileXMISaveImpl.MyEscape.convertText()
		//
		if (value instanceof String) {
			String str = (String) value;
			if (str.indexOf("\n") > 0) { //$NON-NLS-1$
				value = str.replaceAll("\n", LINE_SEP); //$NON-NLS-1$
			}
		}
		;

		int kind = getFeatureKind(feature);

		try {
			// TODO: temporary fix to avoid ArrayIndexOutOfBoundsException,
			// needs revisit
			//
			if (kind == IS_MANY_MOVE) {
				List list = (List) object.eGet(feature);
				if (position > -1 && list.indexOf(value) == -1) {
					return;
				}
			}

			super.setValue(object, feature, value, position);

			switch (kind) {
			case IS_MANY_ADD:
			case IS_MANY_MOVE:
				InternalEList list = (InternalEList) object.eGet(feature);

				// save same document forward (unidirectional) references to
				// resolve at the end of document parsing
				//				
				if (feature instanceof EReference) {
					EReference ref = (EReference) feature;
					if (ref.getEOpposite() != null) {
						InternalEObject owner = (InternalEObject) object;
						for (Iterator iter = list.basicIterator(); iter
								.hasNext();) {
							InternalEObject element = (InternalEObject) iter
									.next();
							if (element.eIsProxy()
									&& element.eProxyURI().trimFragment()
											.equals(resourceURI)) {
								sameDocReferences.add(new ProxyReference(owner,
										ref, element));
							}
						}
					}
				}

				break;
			}
		} catch (RuntimeException e) {
			if (logError) {
				if(MultiFileSaveUtil.DEBUG) {
					e.printStackTrace();
				}
				CommonPlugin.INSTANCE.log(e);
				String errMsg = new StringBuffer(
						"MultiFileXMIHelperImpl.setValue(): ERROR") //$NON-NLS-1$
						.append("\n  object: ").append(object) //$NON-NLS-1$
						.append("\n  feature: ").append(feature) //$NON-NLS-1$
						.append("\n  value: ").append(value) //$NON-NLS-1$
						.append("\n  position: ").append(position) //$NON-NLS-1$
						.append("\n  kind: ").append(kind) //$NON-NLS-1$
						.toString();
				if(MultiFileSaveUtil.DEBUG) {
					System.err.println(errMsg);
				}
				CommonPlugin.INSTANCE.log(errMsg);
			}
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl#getValue(org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EStructuralFeature)
	 */
	public Object getValue(EObject obj, EStructuralFeature f) {
		Object value = super.getValue(obj, f);
		
		// remove any value that does not belong to any resource
		//
		if(f instanceof EReference) {
			if(f.isMany()) {
				if(f.isChangeable() && value instanceof InternalEList) {
					InternalEList list = (InternalEList) value;
					for (Iterator iter = list.iterator(); iter.hasNext();) {
						EObject o = (EObject) iter.next();
						if(!o.eIsProxy() && o.eResource() == null) {
							iter.remove();
						}
					}
				}
			}
			else {
				EObject o = (EObject) value;
				if(!o.eIsProxy() && o.eResource() == null) {
					value = null;
				}
			}
		}
		
		return value;
	}
		
}
