/*******************************************************************************
 * Copyright (C) 2007 The University of Manchester   
 * 
 *  Modifications to the initial code base are copyright of their
 *  respective authors, or their employers as appropriate.
 * 
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1 of
 *  the License, or (at your option) any later version.
 *    
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *    
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 ******************************************************************************/
package net.sf.taverna.wsdl.parser;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.namespace.QName;


/**
 * Base class for all descriptors for type
 * 
 */
public class TypeDescriptor {
	private String name;

	private String type;

	private boolean optional;

	private boolean unbounded;

	private QName qname;

	private boolean nillable = false;
	
	private String documentation;

	public boolean isNillable() {
		return nillable;
	}

	public QName getQname() {
		if (qname != null)
			return qname;
		else {
			return new QName("", type);
		}
	}

	public void setQnameFromString(String qname) {
		String[] split = qname.split("}");
		if (split.length == 1) {
			this.qname = new QName("", qname);
		} else {
			String uri = split[0];
			uri = uri.replaceAll("\\{", "");
			uri = uri.replaceAll("\\}", "");
			this.qname = new QName(uri, split[1]);
		}
	}

	public String getMimeType() {
		return translateJavaType(determineClassType(this));
	}
	
	public void setQname(QName qname) {
		this.qname = qname;
	}

	public String getNamespaceURI() {
		return getQname().getNamespaceURI();
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		int i;
		if ((i = name.lastIndexOf('>')) != -1) {
			this.name = name.substring(i + 1);
		} else {
			this.name = name;
		}
	}
	
	/**
     * @return the depth determined from the syntactic mime type of the original
     *         port. i.e text/plain = 0, l('text/plain') = 1, l(l('text/plain')) =
     *         2, ... etc.
     */
    public int getDepth() {
    	String syntacticType=getMimeType();
        if (syntacticType == null) {
                return 0;
        } else {
                return syntacticType.split("l\\(").length - 1;
        }
    }

	public boolean isOptional() {
		return optional;
	}

	public void setOptional(boolean optional) {
		this.optional = optional;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public boolean isUnbounded() {
		return unbounded;
	}

	public void setUnbounded(boolean unbounded) {
		this.unbounded = unbounded;
	}

	@Override
	public String toString() {
		return name + ":" + type;
	}

	/**
	 * Translate a java type into a taverna type string
	 */
	public static String translateJavaType(Class<?> type) {
		if (type.equals(String[].class)) {
			return "l('text/plain')";
		} else if (type.equals(org.w3c.dom.Element.class)) {
			return "'text/xml'";
		}

		else if (type.equals(org.w3c.dom.Element[].class)) {
			return "l('text/xml')";
		} else if (type.equals(byte[].class)) {
			return "'application/octet-stream'";
		} else {
			return "'text/plain'";
		}
	}

	public static void retrieveSignature(List<TypeDescriptor> params, String[] names,
			Class<?>[] types) {
		for (int i = 0; i < names.length; i++) {
			TypeDescriptor descriptor = params.get(i);
			names[i] = descriptor.getName();
			
			types[i]=determineClassType(descriptor);
		}
	}

	private static Class<?> determineClassType(TypeDescriptor descriptor) {
		String s = descriptor.getType().toLowerCase();
		Class<?> type;
		if (descriptor instanceof ArrayTypeDescriptor) {
			if (((ArrayTypeDescriptor) descriptor).getElementType() instanceof BaseTypeDescriptor) {
				type = String[].class;
			} else if (((ArrayTypeDescriptor) descriptor).isUnbounded()) {
				type = org.w3c.dom.Element[].class;
			}
			else {
				type = org.w3c.dom.Element.class;
			}
		} else {
			if ("string".equals(s)) {
				type = String.class;
			} else if ("double".equals(s) || "decimal".equals(s)) {
				type = Double.TYPE;
			} else if ("float".equals(s)) {
				type = Float.TYPE;
			} else if ("int".equals(s) || "integer".equals(s)) {
				type = Integer.TYPE;
			} else if ("boolean".equals(s)) {
				type = Boolean.TYPE;
			} else if ("base64binary".equals(s)) {
				type = byte[].class;
			} else {
				//treat any other basetype as a String.
				if (descriptor instanceof BaseTypeDescriptor) {
					type=String.class;
				}
				else {
					type = org.w3c.dom.Element.class;
				}
			}
		}
		return type;
	}

	/**
	 * Determines whether the descriptor describes a data structure that is
	 * cyclic, i.e. contains inner elements that contain references to outer
	 * elements, leading to a state of infinate recursion.
	 * 
	 * @param descriptor
	 * @return
	 */
	public static boolean isCyclic(TypeDescriptor descriptor) {
		boolean result = false;
		if (!(descriptor instanceof BaseTypeDescriptor)) {
			if (descriptor instanceof ComplexTypeDescriptor) {
				result = testForCyclic((ComplexTypeDescriptor) descriptor,
						new ArrayList<String>());
			} else {
				result = testForCyclic((ArrayTypeDescriptor) descriptor,
						new ArrayList<String>());
			}
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	private static boolean testForCyclic(ComplexTypeDescriptor descriptor,
			List<String> parents) {
		boolean result = false;
		String descKey = descriptor.getQname().toString();
		if (parents.contains(descKey))
			result = true;
		else {
			parents.add(descKey);
			List elements = descriptor.getElements();
			for (Iterator iterator = elements.iterator(); iterator.hasNext();) {
				TypeDescriptor elementDescriptor = (TypeDescriptor) iterator
						.next();
				if (elementDescriptor instanceof ComplexTypeDescriptor) {
					result = testForCyclic(
							(ComplexTypeDescriptor) elementDescriptor, parents);
				} else if (elementDescriptor instanceof ArrayTypeDescriptor) {
					result = testForCyclic(
							(ArrayTypeDescriptor) elementDescriptor, parents);
				}

				if (result)
					break;
			}

			parents.remove(descKey);
		}
		return result;
	}

	private static boolean testForCyclic(ArrayTypeDescriptor descriptor,
			List<String> parents) {
		boolean result = false;
		String descKey = descriptor.getQname().toString();
		if (parents.contains(descKey))
			result = true;
		else {
			parents.add(descKey);

			TypeDescriptor elementDescriptor = descriptor
					.getElementType();
			if (elementDescriptor instanceof ComplexTypeDescriptor) {
				result = testForCyclic(
						(ComplexTypeDescriptor) elementDescriptor, parents);
			} else if (elementDescriptor instanceof ArrayTypeDescriptor) {
				result = testForCyclic((ArrayTypeDescriptor) elementDescriptor,
						parents);
			}

			parents.remove(descKey);
		}
		return result;
	}

	public void setNillable(boolean nillable) {
		this.nillable  = nillable;
		
		
	}

	public String getDocumentation() {
		return documentation;
	}

	public void setDocumentation(String documentation) {
		this.documentation = documentation;
	}
}
