/*******************************************************************************
 * Copyright (c) 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.bpel.ui.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xsd.XSDAttributeDeclaration;
import org.eclipse.xsd.XSDAttributeGroupDefinition;
import org.eclipse.xsd.XSDAttributeUse;
import org.eclipse.xsd.XSDAttributeUseCategory;
import org.eclipse.xsd.XSDComplexTypeContent;
import org.eclipse.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDFeature;
import org.eclipse.xsd.XSDModelGroup;
import org.eclipse.xsd.XSDModelGroupDefinition;
import org.eclipse.xsd.XSDNamedComponent;
import org.eclipse.xsd.XSDParticle;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
import org.eclipse.xsd.XSDTypeDefinition;
import org.eclipse.xsd.util.XSDConstants;
import org.eclipse.xsd.util.XSDUtil;

/**
 * Collection of utility methods for dealing with navigation of the XSD model
 */
public class XSDUtils {

	// singleton lists of XSD simple type definitions for supported primitives (see getPrimitives()) and
	// all xsd primitives (see getAdvancedPrimitives()) respectively
	private static List<XSDSimpleTypeDefinition> primitives;
	private static List<XSDTypeDefinition> advancedPrimitives;

	// XSD short list -- these are the types presented to the user by default, rather than inundating them with
	// all the available types
	private static List<String> xsdShortList = new ArrayList<String>();
	static
	{
		xsdShortList.add("string"); //$NON-NLS-1$
		xsdShortList.add("int"); //$NON-NLS-1$
		xsdShortList.add("double"); //$NON-NLS-1$
		xsdShortList.add("date"); //$NON-NLS-1$
		xsdShortList.add("time"); //$NON-NLS-1$
		xsdShortList.add("dateTime"); //$NON-NLS-1$
		xsdShortList.add("boolean"); //$NON-NLS-1$
		xsdShortList.add("hexBinary"); //$NON-NLS-1$
		xsdShortList.add("float"); //$NON-NLS-1$
	}


	// A list of all supported XSD types.  Usually the user will not be presented with the full list, but
	// rather with the xsd short list
	private static List<String> supportedPrimitives = new ArrayList<String>();
	static {
		supportedPrimitives.add("anyType"); //$NON-NLS-1$
		supportedPrimitives.add("anyURI"); //$NON-NLS-1$
		supportedPrimitives.add("base64Binary"); //$NON-NLS-1$
		supportedPrimitives.add("boolean"); //$NON-NLS-1$
		supportedPrimitives.add("byte"); //$NON-NLS-1$
		supportedPrimitives.add("date"); //$NON-NLS-1$
		supportedPrimitives.add("dateTime"); //$NON-NLS-1$
		supportedPrimitives.add("decimal"); //$NON-NLS-1$
		supportedPrimitives.add("double"); //$NON-NLS-1$
		supportedPrimitives.add("duration"); //$NON-NLS-1$
		supportedPrimitives.add("ENTITIES"); //$NON-NLS-1$
		supportedPrimitives.add("ENTITY"); //$NON-NLS-1$
		supportedPrimitives.add("float"); //$NON-NLS-1$
		supportedPrimitives.add("gDay"); //$NON-NLS-1$
		supportedPrimitives.add("gMonth"); //$NON-NLS-1$
		supportedPrimitives.add("gMonthDay"); //$NON-NLS-1$
		supportedPrimitives.add("gYear"); //$NON-NLS-1$
		supportedPrimitives.add("gYearMonth"); //$NON-NLS-1$
		supportedPrimitives.add("hexBinary"); //$NON-NLS-1$
		supportedPrimitives.add("ID"); //$NON-NLS-1$
		supportedPrimitives.add("IDREF"); //$NON-NLS-1$
		supportedPrimitives.add("IDREFS"); //$NON-NLS-1$
		supportedPrimitives.add("int"); //$NON-NLS-1$
		supportedPrimitives.add("integer"); //$NON-NLS-1$
		supportedPrimitives.add("language"); //$NON-NLS-1$
		supportedPrimitives.add("long"); //$NON-NLS-1$
		supportedPrimitives.add("Name"); //$NON-NLS-1$
		supportedPrimitives.add("NCName"); //$NON-NLS-1$
		supportedPrimitives.add("negativeInteger"); //$NON-NLS-1$
		supportedPrimitives.add("NMTOKEN"); //$NON-NLS-1$
		supportedPrimitives.add("NMTOKENS"); //$NON-NLS-1$, "NMTOKENS");
		supportedPrimitives.add("nonNegativeInteger"); //$NON-NLS-1$
		supportedPrimitives.add("nonPositiveInteger"); //$NON-NLS-1$
		supportedPrimitives.add("normalizedString"); //$NON-NLS-1$
		supportedPrimitives.add("NOTATION"); //$NON-NLS-1$
		supportedPrimitives.add("positiveInteger"); //$NON-NLS-1$
		supportedPrimitives.add("QName"); //$NON-NLS-1$
		supportedPrimitives.add("short"); //$NON-NLS-1$
		supportedPrimitives.add("string"); //$NON-NLS-1$
		supportedPrimitives.add("time"); //$NON-NLS-1$
		supportedPrimitives.add("token"); //$NON-NLS-1$
		supportedPrimitives.add("unsignedByte"); //$NON-NLS-1$
		supportedPrimitives.add("unsignedInt"); //$NON-NLS-1$
		supportedPrimitives.add("unsignedLong"); //$NON-NLS-1$
		supportedPrimitives.add("unsignedShort"); //$NON-NLS-1$
	}

	/**
	 * Like getPrimitives(), this returns a list of XSDTypeDefinitions.  However where getPrimitives()
	 * returns the basic set supported by the editor, getAdvancedPrimitives returns every known XSD
	 * primitive type.
	 * @return
	 */
	public static List<XSDTypeDefinition> getAdvancedPrimitives() {
		advancedPrimitives = null;
		if(advancedPrimitives == null) {
			advancedPrimitives = new ArrayList<XSDTypeDefinition>();

			// Get the schema for schemas instance to use when resolving primitives
			XSDSchema schemaForSchemas = XSDUtil.getSchemaForSchema(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001);

			// Start adding the simple types using the supportedPrimitives list
			for (String typeName : supportedPrimitives) {
				XSDTypeDefinition type = schemaForSchemas.resolveSimpleTypeDefinition(typeName);
				advancedPrimitives.add(type);
			}

			// Return primitives in alpha order
			Collections.sort(advancedPrimitives, new Comparator() {

				@Override
				public int compare(Object o1, Object o2) {
					if(o1 == null || o2 == null || ((XSDTypeDefinition) o1).getName() == null)
						return 0;
					return ((XSDTypeDefinition) o1).getName().compareToIgnoreCase(((XSDTypeDefinition) o2).getName());
				}
			});
		}
		return advancedPrimitives;
	}

	/**
	 * Given a BO (XSD Complex Type), return a list of the attributes
	 * within the complexType.
	 * @param bo
	 * @return List of XSDAttributeDeclaration
	 */
	public static List<XSDAttributeDeclaration> getChildAttributes(XSDComplexTypeDefinition bo)
	{
		EList attrContents = bo.getAttributeContents();
		List<XSDAttributeDeclaration> attrs = new ArrayList<XSDAttributeDeclaration>();
		for (int i=0; i< attrContents.size(); i++)
		{
			Object next = attrContents.get(i);

			// Attribute contents may include actual attribute delcarations (wrapped in XSDAttributeUses) or
			// attribute group definitions, containing bundles of attributes
			if(next instanceof XSDAttributeUse) {
				attrs.add( ((XSDAttributeUse) next).getContent().getResolvedAttributeDeclaration() );

			} else if (next instanceof XSDAttributeGroupDefinition) {

				// Add these attributes to the end of attrContents to be processed in turn
				XSDAttributeGroupDefinition attrGroup = (XSDAttributeGroupDefinition) next;
				if(attrGroup.getResolvedAttributeGroupDefinition() != null)
					attrContents.addAll(attrGroup.getResolvedAttributeGroupDefinition().getAttributeUses());

			}
		}
		return attrs;
	}

	/**
	 * Given a BO (XSD Complex Type), return a list of the XSDFeatures
	 * within the complexType's modelgroup (sequence, choice, etc.)
	 * @param bo
	 * @return
	 */
	public static List<XSDFeature> getChildElements(XSDComplexTypeDefinition bo) {
   		return XSDUtils.getChildElements( getModelGroup(bo) );
	}

	/**
	 * Given a Model group, return a list of the XSDFeatures
	 * declared within.
	 * @param group
	 * @return
	 */
	public static List<XSDFeature> getChildElements(XSDModelGroup group)
	{
    	if(group == null)
    		return new ArrayList<XSDFeature>();

		List<XSDFeature> children = new ArrayList<XSDFeature>();
    	for( XSDParticle next : group.getContents() ) {
    		if(next.getContent() instanceof XSDFeature)
    			children.add((XSDFeature) next.getContent());
    		else if (next.getTerm() instanceof XSDModelGroup)
    			children.addAll(getChildElements((XSDModelGroup) next.getTerm()));
    	}
    	return children;
	}

	/**
	 * Given an XSD Complex Type Definition, return the model group containing
	 * its child elements.
	 * @param element
	 * @return
	 */
	public static XSDModelGroup getModelGroup(XSDComplexTypeDefinition cType)
	{
		XSDParticle particle = cType.getComplexType();

		// In cases where cType doesn't have a model group AND cType has a parent with a modelgroup, the
		// call above will rather unexpectedly give us cType's PARENT's model group, rather than the null we
		// might expect.  We don't want that here, if the model group returned is null or belongs to someone
		// other than us, return null
		if (particle==null || particle.eContainer() != cType) {
			return null;
		}

		// get the model group
		Object particleContent = particle.getContent();
		XSDModelGroup group = null;

		if (particleContent instanceof XSDModelGroupDefinition) {
		    group = ((XSDModelGroupDefinition)particleContent).getResolvedModelGroupDefinition().getModelGroup();
		} else if (particleContent instanceof XSDModelGroup) {
		    group = (XSDModelGroup)particleContent;
		}

		if (group == null) {
		    return null;
		}

		// if the content of the complex type is empty then the content
		// must be in the complexContent, ie. we're extending another BO.
		// if the group and the type are not in the same resource then
		// we are extending another BO and we don't want to show inherited
		// attributes.
		if ( group.getContents().isEmpty() || group.eResource() != cType.eResource())
		{
			// if we are extending another BO then get the elements
			// we are adding
			if (cType.getBaseType()!=null)
			{
				XSDComplexTypeContent content = cType.getContent();

				if (content instanceof XSDParticle) {
					particleContent = ((XSDParticle)content).getContent();
					if (particleContent instanceof XSDModelGroupDefinition) {
					    group = ((XSDModelGroupDefinition)particleContent).getResolvedModelGroupDefinition().getModelGroup();
					} else if (particleContent instanceof XSDModelGroup) {
					    group = (XSDModelGroup)particleContent;
					}
				}

			}
		}

		return group;
	}

	/**
	 * Try a variety of methods to get a human readable name for type.  In order, this method will
	 * - check whether type is null, and if so return null
	 * - check whether type is a restriction of a primitive type, if so return its parent's name
	 * - check whether type is a complex anonymous (un-named) inner type of a named element, and if so, return the element's name
	 * - check whether type is a primitive type, and if so return a human-readable version of that type
	 * - check whether type is a named, non-primitive type, and if so, return its name
	 * @param xsdType
	 * @return
	 */
	public static String getDisplayNameFromXSDType(XSDTypeDefinition type) {
		return getDisplayNameFromXSDType(type, true);
	}

	/**
	 * Try a variety of methods to get a human readable name for type.  In order, this method will
	 * - check whether type is null, and if so return null
	 * - check whether type is a complex anonymous (un-named) inner type of a named element, and if so, return the element's name
	 * - check whether type is a primitive type, and if so return a human-readable version of that type
	 * - check whether type is a named, non-primitive type, and if so, return its name
	 * - if returnPrimitiveParents is true, check whether type is a restriction of a primitive type,
	 * if so return its parent's name
	 * @param xsdType
	 * @param returnPrimitiveParents if true, and if type is an anonymous restriction of an xsd primitive
	 * type, this method will return the name of the parent primitive type.  If false, restrictions of
	 * primitive types will not be treated differently from other types, and their container hierarchy will
	 * be walked, instead of their inheritance hierarchy.
	 * @return
	 */
	public static String getDisplayNameFromXSDType(XSDTypeDefinition type, boolean returnPrimitiveParents) {
		if(type == null)
			return null;

		// Does type have a name?  If not, walk up the container tree to try and find one
		if(type.getName() == null || type.getName().length() == 0) {

			// In the special case where type is a restriction on a primitive type, just return the parent's
			// name (which will either be a primitive itself, or a named simple type)
			if(returnPrimitiveParents && isRestrictedPrimitiveType(type)) {
				return getDisplayNameFromXSDType(type.getBaseType());
			}

			EObject container = type.eContainer();

			while(container != null) {
				if(container instanceof XSDNamedComponent && ((XSDNamedComponent) container).getName() != null) {
					return ((XSDNamedComponent) container).getName();
				}
				container = container.eContainer();
			}
			// Type doesn't have a name, or a container with a name, nothing useful
			return null;
		} else
			return type.getName();
	}

	/**
	 * Return the type definition for the primitive with name xsdName (note, this is not the human-readable
	 * name, but the actual XSD type name.)  Return null if a type with this name is not in the list of
	 * all primitives
	 * @param xsdName
	 * @return
	 */
	public static XSDSimpleTypeDefinition getPrimitive(String xsdName) {
		for( XSDTypeDefinition xsdTypeDefinition : getAdvancedPrimitives() ) {
			XSDSimpleTypeDefinition next = (XSDSimpleTypeDefinition) xsdTypeDefinition;
			if(next.getName().equals(xsdName)) {
				return next;
			}
		}
		return null;
	}

	/**
	 *
	 * @return Returns a list of XSDSimpleTypeDefinitions representing each of the supported primitives.
	 * These will have their XSD spec names (e.g. xsd:dateTime) so they will likely need to be fed to
	 * getDisplayName() if they are going to be presented to humans
	 */
	public static List<XSDSimpleTypeDefinition> getPrimitives() {
		if(primitives == null) {
			primitives = new ArrayList<XSDSimpleTypeDefinition>();

			// Get the schema for schemas instance to use when resolving primitives
			XSDSchema schemaForSchemas = XSDUtil.getSchemaForSchema(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001);

			// Start adding the simple types from the XSD short list
			for( String typeName : xsdShortList ) {
				XSDSimpleTypeDefinition type = schemaForSchemas.resolveSimpleTypeDefinition(typeName);
				primitives.add(type);
			}

			// Return primitives in alpha order
			Collections.sort(primitives, new Comparator() {

				@Override
				public int compare(Object o1, Object o2) {
					if(o1 == null || o2 == null || getDisplayNameFromXSDType((XSDTypeDefinition) o1) == null)
						return 0;
					return getDisplayNameFromXSDType((XSDTypeDefinition) o1).compareTo(getDisplayNameFromXSDType((XSDTypeDefinition) o2));
				}
			});
		}
		return primitives;
	}

	/**
	 * Return the base type from which this type inherits - that is, all xsd types are
	 * either xsd:anyType or xsd:anySimpleType at the topmost level of inheritance, so return the second
	 * topmost level of type's inheritance.  The first specific type from which type inherits.
	 * @param type
	 * @return
	 */
	public static XSDTypeDefinition getRootType(XSDTypeDefinition type) {
		if(type == null)
			return null;

		XSDTypeDefinition baseType = type.getBaseType();
		while(baseType != null && !XSDConstants.isAnySimpleType(baseType) && !XSDConstants.isAnyType(baseType)) {
			// walk one more step up the hierarchy
			type = baseType;
			baseType = type.getBaseType();
		}

		// Since baseType, type's immediate parent, broke the while condition, we know that type is now
		// as high up the tree as we want to be
		return type;
	}

	/**
	 * Return true if type is a descendant of a primitive xsd type.  Will not return true for primitives
	 * themselves.
	 * @param type
	 * @return
	 */
	public static boolean isRestrictedPrimitiveType(XSDTypeDefinition type) {
		if(type instanceof XSDComplexTypeDefinition)
			return false;

		XSDTypeDefinition baseType = getRootType(type);
		return getAdvancedPrimitives().contains(baseType);
	}

	/**
	 * Gets the "minOccurs" attribute value for the given XSDFeature, if
	 * there is none then it returns the default 1.
	 * @param xsdElem
	 * @return
	 */
	public static int getMinOccurs(XSDFeature xsdElem)
	{
		if (xsdElem.eContainer() instanceof XSDAttributeUse)
		{
			return (((XSDAttributeUse)xsdElem.eContainer()).getUse()==XSDAttributeUseCategory.REQUIRED_LITERAL?1:0);
		}

		XSDParticle particle = (XSDParticle)xsdElem.eContainer();
		int min = 1;
		if (particle.isSetMinOccurs())
			min = particle.getMinOccurs();

		return min;
	}

	/**
	 * Gets the "maxOccurs" attribute value for the given XSDFeature, if
	 * there is none then it returns the default 1.
	 * @param xsdElem
	 * @return
	 */
	public static int getMaxOccurs(XSDFeature xsdElem)
	{
		int max = 1;

		// not a particle means an attribute use.  attributes are maxed at 1.
		if ( !(xsdElem.eContainer() instanceof XSDParticle) )
			return max;

		XSDParticle particle = (XSDParticle)xsdElem.eContainer();
		if (particle.isSetMaxOccurs())
			max = particle.getMaxOccurs();

		return max;
	}

	/**
	 * Return the enclosing Complex Type definition.
	 * @param component
	 * @return
	 */
	public static XSDComplexTypeDefinition getEnclosingTypeDefinition(EObject component)
	{
		if (component == null)
			return null;

		if (component instanceof XSDComplexTypeDefinition)
			return (XSDComplexTypeDefinition)component;

		return getEnclosingTypeDefinition(component.eContainer());
	}

	/**
	 * Given an XSD complex type, return a list of the XSDFeatures (element
	 * and attribute declarations) within the complex type.
	 */
	public static List<XSDFeature> getXSDElementsAndAttributes(XSDComplexTypeDefinition complexType) {
		List<XSDFeature> result = getChildElements(complexType);
		result.addAll( getChildAttributes(complexType));

		return result;
	}
}
