/*******************************************************************************
 * Copyright (c) 2003, 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 API and implementation
 *******************************************************************************/
package org.eclipse.wst.common.internal.emf.resource;


import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.impl.EStructuralFeatureImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.wst.common.internal.emf.utilities.ExtendedEcoreUtil;
import org.eclipse.wst.common.internal.emf.utilities.FeatureValueConverter;
import org.w3c.dom.Node;


public class Translator {

	public final static int NO_STYLE = 0;
	public final static int DOM_ATTRIBUTE = 1;
	public final static int EMPTY_TAG = 1 << 1;
	public final static int CDATA_CONTENT = 1 << 2;
	/**
	 * Style bit that indicates that the end tag should NOT be indented; by default it is.
	 */
	public final static int END_TAG_NO_INDENT = 1 << 3;
	/**
	 * Style bit that indicates that booleans should NOT be converted as "True" and "False"; default
	 * is that they are
	 */
	public final static int BOOLEAN_LOWERCASE = 1 << 4;
	/**
	 * Style bit that indicates an enum value contains hyphens If this is true, then internally the
	 * hyphens are replaced with underscores
	 */
	public final static int ENUM_FEATURE_WITH_HYPHENS = 1 << 5;

	protected final static int OBJECT_MAP = 1 << 6;
	protected final static int BOOLEAN_FEATURE = 1 << 7;

	protected final static int SHARED_REFERENCE = 1 << 8;

	/**
	 * Indicates that the feature may be significant even if it is empty
	 */
	public final static int EMPTY_CONTENT_IS_SIGNIFICANT = 1 << 9;

	/**
	 * Used to indicate that feature is associated with a comment node
	 */
	protected final static int COMMENT_FEATURE = 1 << 10;

	/**
	 * If the value is null, then an eUnset() will be invoked on the feature
	 */
	public final static int UNSET_IF_NULL = 1 << 11;

	/**
	 * Return the element contents as a String if the feature is unresolveable (Used by the
	 * SourceLinkTranslator)
	 */
	public final static int STRING_RESULT_OK = 1 << 12;

	protected String[] fDOMNames;
	protected String fDOMPath = ""; //$NON-NLS-1$
	protected Map readAheadNames;
	protected int fStyle = NO_STYLE;
	protected EStructuralFeature feature;
	protected TranslatorPath[] fTranslatorPaths;
	protected EClass emfClass;
	protected String fNameSpace = ""; //$NON-NLS-1$
	// added by MDE
	protected String domNameAndPath = null;

	/**
	 * Indicates if any of the children of this Translator are themselves DependencyTranslators
	 */
	protected Boolean isDependencyParent;
	protected EStructuralFeature dependencyFeature;
	protected static EcorePackage ECORE_PACKAGE = EcorePackage.eINSTANCE;

	// Use this identifier for the DOMName when the attribute
	// value is to be extracted directly from the text of the node.
	// This is rare, but occurs in the web.xml in the case of a
	// WelcomeFile.
	static final public String TEXT_ATTRIBUTE_VALUE = "$TEXT_ATTRIBUTE_VALUE"; //$NON-NLS-1$

	static final public EStructuralFeature CONTAINER_FEATURE = new ContainerFeature();

	static final public EStructuralFeature ROOT_FEATURE = new RootFeature();

	protected static class ContainerFeature extends EStructuralFeatureImpl {
		protected ContainerFeature() {
			super();
		}
	}

	protected static class RootFeature extends EStructuralFeatureImpl {
		protected RootFeature() {
			super();
		}
	}

	public Translator findChild(String tagName, Object target, int versionID) {

		Translator result = null;
		Translator[] maps = getChildren(target, versionID);

		if (maps != null) {
			for (int i = 0; i < maps.length; i++) {
				Translator map = maps[i];
				if (map.isMapFor(tagName)) {
					result = map;
					break;
				}
			}
		}
		if (result == null) {
			VariableTranslatorFactory factory = getVariableTranslatorFactory();
			if (factory != null && factory.accepts(tagName)) {
				result = factory.create(tagName);
			}
		}
		return result;
	}

	/**
	 * Utility method to string together arrays of children
	 */
	public static Object[] concat(Object[] array1, Object[] array2) {
		Object[] result = (Object[]) java.lang.reflect.Array.newInstance(array1.getClass().getComponentType(), array1.length + array2.length);
		System.arraycopy(array1, 0, result, 0, array1.length);
		System.arraycopy(array2, 0, result, array1.length, array2.length);
		return result;
	}

	public static Object[] concat(Object[] array1, Object object2) {
		Object[] newArray = new Object[]{object2};
		return concat(array1, newArray);
	}

	public static Translator createParentAndTextAttributeTranslator(String domName, EStructuralFeature parentFeature, EStructuralFeature childFeature) {
		GenericTranslator parent = new GenericTranslator(domName, parentFeature, END_TAG_NO_INDENT);
		parent.setChildren(new Translator[]{new Translator(TEXT_ATTRIBUTE_VALUE, childFeature)});
		return parent;
	}

	public Translator(String domNameAndPath, EClass eClass) {
		initializeDOMNameAndPath(domNameAndPath);
		setEMFClass(eClass);
	}

	public Translator(String domNameAndPath, EStructuralFeature aFeature) {
		initializeDOMNameAndPath(domNameAndPath);
		setFeature(aFeature);
	}

	public Translator(String domNameAndPath, EStructuralFeature aFeature, EClass eClass) {
		this(domNameAndPath, aFeature);
		setEMFClass(eClass);
	}

	public Translator(String domNameAndPath, EStructuralFeature aFeature, TranslatorPath path) {
		this(domNameAndPath, aFeature, new TranslatorPath[]{path});
	}

	public Translator(String domNameAndPath, EStructuralFeature aFeature, TranslatorPath[] paths) {
		initializeDOMNameAndPath(domNameAndPath);
		fTranslatorPaths = paths;
		setFeature(aFeature);
	}

	public Translator(String domNameAndPath, EStructuralFeature aFeature, int style) {
		initializeDOMNameAndPath(domNameAndPath);
		fStyle = style;
		setFeature(aFeature);
	}

	public static EcorePackage getEcorePackage() {
		return EcorePackage.eINSTANCE;
	}

	public String getDOMName(Object value) {
		return fDOMNames[0];
	}

	public String[] getDOMNames() {
		return fDOMNames;
	}

	public String getDOMPath() {
		return fDOMPath;
	}

	public boolean hasDOMPath() {
		return fDOMPath != null && fDOMPath.length() != 0;
	}

	public EStructuralFeature getFeature() {
		return feature;
	}

	/**
	 * Parse the DOM names and path out of <domNameAndPath>and set the appropriate fields.
	 */
	protected void initializeDOMNameAndPath(String domNameAndPathArg) {
		if (domNameAndPathArg == null)
			return;
		int inx = domNameAndPathArg.lastIndexOf('/');
		if (inx != -1) {
			fDOMNames = parseDOMNames(domNameAndPathArg.substring(inx + 1));
			fDOMPath = domNameAndPathArg.substring(0, inx);
		} else {
			fDOMNames = parseDOMNames(domNameAndPathArg);
			fDOMPath = ""; //$NON-NLS-1$
		}
		// added by MDE
		this.domNameAndPath = domNameAndPathArg;

	}

	/**
	 * Indicates whether the node should be written as an empty tag; eg, <distributable/>
	 */
	public boolean isCDATAContent() {
		return (fStyle & CDATA_CONTENT) != 0;
	}

	/**
	 * Indicates whether the DOMName represents a sub element name or an attribute name
	 * 
	 * @return boolean True if the DOMName is an attribute name.
	 */
	public boolean isDOMAttribute() {
		return (fStyle & DOM_ATTRIBUTE) != 0;
	}

	/**
	 * Indicates whether the node should be written as an empty tag; eg, <distributable/>
	 */
	public boolean isEmptyTag() {
		return (fStyle & EMPTY_TAG) != 0;
	}

	public boolean isBooleanUppercase() {
		return (fStyle & BOOLEAN_FEATURE) != 0 && (fStyle & BOOLEAN_LOWERCASE) == 0;
	}

	public boolean isBooleanFeature() {
		return (fStyle & BOOLEAN_FEATURE) != 0;
	}

	public boolean shouldIndentEndTag() {
		return (fStyle & END_TAG_NO_INDENT) == 0;
	}

	public boolean shouldIndentEndTag(Node node) {
		return shouldIndentEndTag();
	}

	public boolean isEmptyContentSignificant() {
		return ((fStyle & EMPTY_TAG) != 0) || ((fStyle & EMPTY_CONTENT_IS_SIGNIFICANT) != 0);
	}

	/**
	 * Returns true if this map is to another MOF object (not a primitive)
	 */
	public boolean isObjectMap() {
		return (fStyle & OBJECT_MAP) != 0;
	}

	/**
	 * Returns true if this map is for a shared reference
	 */
	public boolean isShared() {
		return (fStyle & SHARED_REFERENCE) != 0;
	}

	public boolean isEnumWithHyphens() {
		return (fStyle & ENUM_FEATURE_WITH_HYPHENS) != 0;
	}

	/**
	 * Indicates whether the map represents a case where the text of the DOMNode represents the
	 * objects one and only attribute value. An example of this case is a <welcome-file>file.txt
	 * </welcome-file>.
	 */
	public boolean isDOMTextValue() {
		return fDOMNames[0] == TEXT_ATTRIBUTE_VALUE;
	}

	/**
	 * Indicates whether the id is the mof attribute that should be set.
	 */
	public boolean isIDMap() {
		return false;
	}

	/**
	 * Indicates whether the id is the mof attribute that should be set.
	 */
	public boolean isLinkMap() {
		return fTranslatorPaths != null;
	}

	public boolean isTargetLinkMap() {
		return isLinkMap() && !isObjectMap();
	}

	/**
	 * Return true if this map is the one representing a node with the name <domName>. By default
	 * this method simply compares the DOM name of the map against the <domName>parameter
	 * 
	 * @return boolean
	 * @param domName
	 *            java.lang.String
	 */
	public boolean isMapFor(String domName) {
		if (domName.equals(getDOMPath()))
			return true;
		for (int i = 0; i < fDOMNames.length; i++) {
			if (domName.equals(fDOMNames[i]))
				return true;
		}
		return false;
	}

	public boolean isMapFor(Object aFeature, Object oldValue, Object newValue) {
		return feature == aFeature;
	}

	/**
	 * Indicates whether feature being mapped is a collection.
	 * 
	 * @return boolean True if the feature is multi valued.
	 */
	public boolean isMultiValued() {
		if (feature != null)
			return feature.isMany();
		return false;
	}

	/**
	 * Parses comma separated names from <domNamesString>. Returns an array containing the names.
	 * 
	 * @return java.lang.String[]
	 * @param domNamesString
	 *            java.lang.String
	 */
	protected String[] parseDOMNames(String domNamesString) {
		int startInx = 0;
		int inx = domNamesString.indexOf(',');
		ArrayList results = new ArrayList(1);
		while (inx != -1) {
			results.add(domNamesString.substring(startInx, inx));
			startInx = inx + 1;
			inx = domNamesString.indexOf(',', startInx);
		}
		if (startInx == 0)
			results.add(domNamesString);
		else
			results.add(domNamesString.substring(startInx));
		return (String[]) results.toArray(new String[results.size()]);
	}

	public String toString() {
		StringBuffer sb = new StringBuffer();
		String cn = getClass().getName();
		int i = cn.lastIndexOf('.');
		cn = cn.substring(++i, cn.length());
		sb.append(cn);
		sb.append('(');
		sb.append(fDOMNames[0]);
		for (int j = 1; j < fDOMNames.length; j++) {
			sb.append('|');
			sb.append(fDOMNames[j]);
		}
		sb.append(',');
		sb.append(hashCode());
		sb.append(')');
		return sb.toString();
	}

	/**
	 * Gets the TranslatorPath.
	 * 
	 * @return Returns a TranslatorPath
	 */
	public TranslatorPath[] getTranslatorPaths() {
		return fTranslatorPaths;
	}

	/*
	 * @see Object#equals(Object)
	 */
	public boolean equals(Object object) {
		if (!(object instanceof Translator))
			return false;
		Translator mapInfo = (Translator) object;
		return fDOMNames.equals(mapInfo.getDOMNames()) && (feature == null && mapInfo.getFeature() == null || feature.equals(mapInfo.getFeature()));
	}

	/**
	 * Returns the isManagedByParent.
	 * 
	 * @return boolean
	 */
	public boolean isManagedByParent() {
		return getChildren(null, -1) == null;
	}

	/*
	 * In the 99% case there is only one node name to be concerned with, but subclasses can override
	 * for the cases where multiple dom names map to one feature
	 */
	public EObject createEMFObject(String nodeName, String readAheadName) {
		if (emfClass == null) {
			if (feature == null)
				return null;
			if (isObjectMap())
				return createEMFObject(feature);
		}
		return createEMFObject(emfClass);
	}

	public static EObject createEMFObject(EStructuralFeature aFeature) {
		if (aFeature == null)
			return null;

		return createEMFObject(((EReference) aFeature).getEReferenceType());
	}

	public static EObject createEMFObject(EClass anEClass) {
		if (anEClass == null)
			return null;
		return anEClass.getEPackage().getEFactoryInstance().create(anEClass);
	}

	public void setTextValueIfNecessary(String textValue, Notifier owner, int versionId) {
		Translator textTranslator = this.findChild(Translator.TEXT_ATTRIBUTE_VALUE, owner, versionId);
		if (textTranslator != null) {
			Object objectValue = textTranslator.convertStringToValue(textValue, (EObject) owner);
			textTranslator.setMOFValue(owner, objectValue);
		}
	}

	/**
	 * Check to see if feature is valid on a particular mofObject.
	 * 
	 * @return boolean Return true if the feature specified exists on the MOF object.
	 * @param emfObject
	 *            org.eclipse.emf.ecore.EObject
	 */
	public boolean featureExists(EObject emfObject) {
		if (feature == null)
			return false;

		return emfObject.eClass().getEStructuralFeature(feature.getName()) != null;
	}

	/**
	 * Translators which do not have a feature should override this method with custom behavior.
	 */
	public String extractStringValue(EObject emfObject) {
		if (isEmptyTag() && feature == null)
			return ""; //Fake it out with a value //$NON-NLS-1$
		return null;
	}

	public Object convertStringToValue(String nodeName, String readAheadName, String value, Notifier owner) {
		Object result = null;
		try {

			if (!this.isManagedByParent()) {
				result = createEMFObject(nodeName, readAheadName);
			} else {
				result = convertStringToValue(value, (EObject) owner);
			}

		} catch (ClassCastException cce) {

		}
		return result;
	}

	/**
	 * Converts a string value to the appropriate type.
	 * 
	 * @return java.lang.Object The converted value
	 * @param strValue
	 *            java.lang.String The string to convert.
	 */
	public Object convertStringToValue(String strValue, EObject owner) {
		if (feature == null)
			return strValue;
		if (strValue != null) {
			if (isEnumWithHyphens())
				strValue = strValue.replace('-', '_');
			if (!isCDATAContent()) {
				strValue = strValue.trim();
			}
		}
		Object value = FeatureValueConverter.DEFAULT.convertValue(strValue, feature);
		if (value == null) {
			if (isEmptyTag() && !isDOMAttribute() && !isDOMTextValue() && isBooleanFeature())
				return Boolean.TRUE;
			EObject convertToType = feature.getEType();
			if (convertToType == null)
				value = strValue;
			else if (convertToType.equals(getEcorePackage().getEString())) {
				value = ""; //$NON-NLS-1$
			}
		}
		return value;
	}

	/**
	 * Converts a value of a specified type to a string value. Subclasses may override for special
	 * cases where special conversion needs to occur based on the feature and or object type.
	 * 
	 * @return String The converted value
	 * @param value
	 *            java.lang.Object The object to convert.
	 */
	public String convertValueToString(Object value, EObject owner) {
		if (isEmptyTag() || value == null)
			return null;
		else if (isEnumWithHyphens())
			return value.toString().replace('_', '-');
		else if (isBooleanUppercase())
			return ((Boolean) value).booleanValue() ? "True" : "False"; //$NON-NLS-1$ //$NON-NLS-2$

		return value.toString();
	}

	public Translator[] getVariableChildren(Notifier target, int version) {
		Translator[] results = null;
		VariableTranslatorFactory factory = getVariableTranslatorFactory();
		if (factory != null) {
			List variableTranslators = factory.create(target);
			if (variableTranslators != null && variableTranslators.size() > 0) {
				Object[] vtoa = variableTranslators.toArray();

				results = new Translator[vtoa.length];
				for (int i = 0; i < results.length; i++)
					results[i] = (Translator) vtoa[i];
			}

		}
		if (results == null)
			results = new Translator[0];
		return results;
	}

	/**
	 * Returns null by default; subclasses should override to return specific children
	 */
	public Translator[] getChildren(Object target, int versionID) {
		return getChildren();
	}

	protected Translator[] getChildren() {
		return null;
	}

	/**
	 * Return the list of MOF children that currently exist for the values of an attribute.
	 */
	public List getMOFChildren(EObject mofObject) {
		if (feature == null)
			return Collections.EMPTY_LIST;
		Object value = getMOFValue(mofObject);
		List result = Collections.EMPTY_LIST;
		if (isMultiValued())
			result = (List) value;
		else if (value != null)
			result = Collections.singletonList(value);
		return result;
	}

	public Object getMOFValue(EObject mofObject) {
		if (feature == null)
			return null;
		return mofObject.eGet(feature);
	}

	/**
	 * Sets a value of a feature in a mof object.
	 */
	public void setMOFValue(Notifier owner, Object value, int newIndex) {
		if (feature != null) {
			if ((fStyle & UNSET_IF_NULL) != 0 && value == null)
				ExtendedEcoreUtil.eUnsetOrRemove((EObject) owner, feature, value);
			else
				ExtendedEcoreUtil.eSetOrAdd((EObject) owner, feature, value, newIndex);
		}
	}

	public void setMOFValue(Notifier owner, Object value) {
		if (owner instanceof EObject) {
			setMOFValue((EObject) owner, value);
		} else if (owner instanceof Resource) {
			setMOFValue((Resource) owner, value);
		}
	}

	public void setMOFValue(EObject emfObject, Object value) {
		//		if (feature != null)
		//			emfObject.eSet(feature, value);
		setMOFValue(emfObject, value, -1);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.etools.emf2xml.impl.Translator#setMOFValue(org.eclipse.emf.ecore.EObject,
	 *      java.lang.Object)
	 */
	public void setMOFValue(Resource res, Object value) {
		if (res != null && value != null)
			res.getContents().add((EObject)value);
	}

	public void removeMOFValue(Notifier owner, Object value) {
		if (feature != null)
			ExtendedEcoreUtil.eUnsetOrRemove((EObject) owner, feature, value);
	}

	public boolean isSetMOFValue(EObject emfObject) {
		boolean isSet = feature != null && emfObject.eIsSet(feature);
		if (isEmptyTag())
			return isSet && ((Boolean) emfObject.eGet(feature)).booleanValue();
		return isSet;
	}

	public void unSetMOFValue(EObject emfObject) {
		if (feature != null)
			emfObject.eUnset(feature);
	}

	public void clearList(EObject mofObject) {
		if (feature != null)
			((List) mofObject.eGet(feature)).clear();
	}

	protected void setFeature(EStructuralFeature aFeature) {
		this.feature = aFeature;
		if (feature == null)
			return;
		//This way an instance check happens only once
		if (aFeature instanceof EReference) {
			fStyle |= OBJECT_MAP;
			if (!((EReference) aFeature).isContainment())
				fStyle |= SHARED_REFERENCE;
		}

		if (getEcorePackage().getEBoolean() == feature.getEType())
			fStyle |= BOOLEAN_FEATURE;
	}

	protected void setEMFClass(EClass anEClass) {
		this.emfClass = anEClass;
		if (anEClass != null)
			fStyle |= OBJECT_MAP;

	}

	public boolean hasReadAheadNames() {
		return readAheadNames != null && !readAheadNames.isEmpty();
	}

	/**
	 * Return the read ahead names, if they are defined, for a given parent node name. This is used
	 * when creation of a specific EMF object is dependent on the value of a child node.
	 */
	public ReadAheadHelper getReadAheadHelper(String parentName) {
		if (readAheadNames == null)
			return null;
		return (ReadAheadHelper) readAheadNames.get(parentName);
	}

	public void addReadAheadHelper(ReadAheadHelper helper) {
		if (readAheadNames == null)
			readAheadNames = new HashMap(3);
		readAheadNames.put(helper.getParentDOMName(), helper);
	}

	public boolean isDependencyChild() {
		return false;
	}

	/**
	 * @return
	 */
	public boolean isDependencyParent() {
		if (isDependencyParent == null) {
			isDependencyParent = Boolean.FALSE;
			Translator[] theChildren = getChildren(null, -1);
			if (theChildren != null) {
				for (int i = 0; i < theChildren.length; i++) {
					//For now we assume one
					if (theChildren[i].isDependencyChild()) {
						isDependencyParent = Boolean.TRUE;
						dependencyFeature = theChildren[i].getDependencyFeature();
					}
				}
			}
		}
		return isDependencyParent.booleanValue();
	}

	/**
	 * @return
	 */
	public EStructuralFeature getDependencyFeature() {
		return dependencyFeature;
	}

	public EObject basicGetDependencyObject(EObject parent) {
		return (EObject) parent.eGet(dependencyFeature);
	}

	/**
	 * Use when the DOM path is not null, and there are no children. Default is false, but
	 * subclasses may wish to override
	 */
	public boolean shouldRenderEmptyDOMPath(EObject eObject) {
		return isEmptyContentSignificant();
	}

	/**
	 * Use when the translator tolerates parent nodes that relate to the DOM path, and no children;
	 * default is do nothing
	 */
	public void setMOFValueFromEmptyDOMPath(EObject eObject) {

	}

	/**
	 * Namespace for the attributes
	 * 
	 * @return
	 */
	public String getNameSpace() {
		return fNameSpace;
	}

	/**
	 * Set the namespace for the dom attribute
	 * 
	 * @param string
	 */
	public void setNameSpace(String string) {
		fNameSpace = string;
	}

	public VariableTranslatorFactory getVariableTranslatorFactory() {
		if (isObjectMap())
			return DefaultTranslatorFactory.INSTANCE;
		return null;
	}

	public boolean isEnumFeature() {
		return feature != null && ECORE_PACKAGE.getEEnum().isInstance(feature.getEType());
	}

	public boolean isUnsettable() {
		return feature != null && feature.isUnsettable();
	}

	public boolean isDataType() {
		return feature != null && feature.getEType() instanceof EDataType;
	}

	/**
	 * @return
	 */
	public boolean isComment() {
		return (fStyle & COMMENT_FEATURE) != 0;
	}

}
