/*******************************************************************************
 * Copyright (c) 2006 Oracle Corporation.
 * 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:
 *    Cameron Bateman/Oracle - initial API and implementation
 *    
 ********************************************************************************/

package org.eclipse.jst.jsf.common.util;

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

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.ITypeParameter;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
import org.eclipse.jst.jsf.common.internal.types.TypeConstants;

/**
 * Utility for handling IType's and type signatures
 * 
 * Class is static and cannot be extended or instantiated.
 * 
 * @author cbateman
 *
 */
public final class TypeUtil 
{
    static IType resolveType(final IType owningType, final String typeSignature)
    {
        // if type signature is already resolved then simply look it up
        if (typeSignature.charAt(0) == Signature.C_RESOLVED
        		|| (Signature.getTypeSignatureKind(typeSignature) == Signature.BASE_TYPE_SIGNATURE)
        		|| (Signature.getTypeSignatureKind(typeSignature) == Signature.ARRAY_TYPE_SIGNATURE
        			&& Signature.getElementType(typeSignature).charAt(0) == Signature.C_RESOLVED))
        {
            IType type = null;
            
            try
            {
                type = owningType.getJavaProject().
                           findType(getFullyQualifiedName(typeSignature));
            }
            catch (JavaModelException jme)
            {
                // do nothing; return type == null;
            }
            
            return type;
        }
        
        
        return resolveTypeRelative(owningType, typeSignature);
    }

    /**
     * Fully equivalent to:
     * 
     * #resolveTypeSignature(owningType, typeSignature, true)
     * 
     * If resolved, type signature has generic type parameters erased (absent).
     * 
     * @param owningType
     * @param typeSignature
     * @return the resolved type signature for typeSignature in owningType or
     * typeSignature unchanged if cannot resolve.
     */
    public static String resolveTypeSignature(final IType owningType, final String typeSignature)
    {
        return resolveTypeSignature(owningType, typeSignature, true);
    }
    
    /**
     * Resolve typeSignature in the context of owningType.  This method will return 
     * a type erased signture if eraseTypeParameters == true and will attempt to
     * resolve and include parameters if eraseTypeParamters == false
     * 
     * NOTE: special rules apply to the way unresolved type parameters and wildcards
     * are resolved:
     * 
     * 1) If a fully unresolved type parameter is found, then it will be replaced with Ljava.lang.Object;
     * 
     * i.e.  List<T>  -> Ljava.util.List<Ljava.lang.Object;>;  for any unresolved T.
     * 
     * 2) Any bounded wildcard will be replaced by the bound:
     * 
     * i.e. List<? extends String> -> Ljava.util.List<Ljava.lang.String;>;
     * i.e. List<? super String> -> Ljava.util.List<Ljava.lang.String;>;
     * 
     * Note limitation here: bounds that use 'super' will take the "best case" scenario that the list
     * type is of that type.
     * 
     * 3) The unbounded wildcard will be replaced by Ljava.lang.Object;
     * 
     * i.e. List<?> -> Ljava.util.List<Ljava.lang.Object;>;
     * 
     * 
     * The reason for this substition is to return the most accurate reasonable approximation
     * of the type within what is known by owningType
     * 
     * @param owningType
     * @param typeSignature
     * @param eraseTypeParameters if set to false, type parameters are resolved included
     * in the signature
     * @return the resolved type signature for typeSignature in owningType or
     * typeSignature unchanged if cannot resolve.
     */
    public static String resolveTypeSignature(final IType owningType, final String typeSignature, boolean eraseTypeParameters)
    {
        final int sigKind = Signature.getTypeSignatureKind(typeSignature);
    
        switch (sigKind)
        {
            case Signature.BASE_TYPE_SIGNATURE:
                return typeSignature;
                
            case Signature.ARRAY_TYPE_SIGNATURE:
            {
                final String elementType = Signature.getElementType(typeSignature);
                
                if (Signature.getTypeSignatureKind(elementType) == Signature.BASE_TYPE_SIGNATURE)
                {
                    return typeSignature;
                }

                final String resolvedElementType = resolveSignatureRelative(owningType, elementType, eraseTypeParameters);
                String resultType = ""; //$NON-NLS-1$
                for (int i = 0; i < Signature.getArrayCount(typeSignature);i++)
                {
                    resultType+=Signature.C_ARRAY;
                }
                
                return resultType+resolvedElementType;
            }

            case Signature.TYPE_VARIABLE_SIGNATURE:
            	return resolveSignatureRelative(owningType, typeSignature, eraseTypeParameters);
            
            case Signature.CLASS_TYPE_SIGNATURE:
                return resolveSignatureRelative(owningType, typeSignature, eraseTypeParameters);

            case Signature.WILDCARD_TYPE_SIGNATURE:
                // strip the wildcard and try again.  Too bad Signature doesn't seem to have a method
                // for this
                if (typeSignature.charAt(0) == Signature.C_STAR)
                {
                    return TypeConstants.TYPE_JAVAOBJECT;
                }
                return resolveTypeSignature(owningType, typeSignature.substring(1), eraseTypeParameters);
            
            case Signature.CAPTURE_TYPE_SIGNATURE:
                // strip the capture and try again
                return resolveTypeSignature(owningType, Signature.removeCapture(typeSignature), eraseTypeParameters);
//            case Signature.TYPE_VARIABLE_SIGNATURE:
//                resolveSignatureRelative(owningType, typeSignature, eraseTypeParameters);

            default:
                return typeSignature;
        }
    }
    
    /**
     * @param owningType -- type relative to which typeSignature will be resolved
     * @param typeSignature -- non-array type signature
     * @return the resolved type signature if possible or typeSignature if not
     */
    private static String resolveSignatureRelative(final IType owningType, final String typeSignature, final boolean eraseTypeParameters)
    {
        // if already fully resolved, return the input
        if (typeSignature.charAt(0) == Signature.C_RESOLVED)
        {
            return typeSignature;
        }

        List<String> typeParameters = new ArrayList<String>();

        IType resolvedType = resolveTypeRelative(owningType, typeSignature);

        if (resolvedType != null)
        {
            if (!eraseTypeParameters)
            {
                // ensure that type parameters are resolved recursively
                for (String typeParam : Signature.getTypeArguments(typeSignature))
                {
                    typeParam = Signature.removeCapture(typeParam);
                    // check and remove bound wildcarding (extends/super/?)
                    if (Signature.getTypeSignatureKind(typeParam) == Signature.WILDCARD_TYPE_SIGNATURE)
                    {
                        // convert ? to Object, strip extends/super
                        if (typeParam.charAt(0) == Signature.C_STAR)
                        {
                            typeParam = TypeConstants.TYPE_JAVAOBJECT;
                        }
                        else
                        {
                            typeParam = typeParam.substring(1);
                        }
                    }
                    final String resolvedParameter = 
                    	resolveSignatureRelative(
                    			// use the enclosing type, 
                    			// *not* the resolved type because 
                    			// we need to resolve in that context
                    			owningType, 
                    				typeParam, eraseTypeParameters);
                    typeParameters.add(resolvedParameter);
                }
            }

            final String  resolvedTypeSignature = 
                Signature.createTypeSignature
                    (resolvedType.getFullyQualifiedName(), true);
           

            if (typeParameters.size() > 0 && !eraseTypeParameters)
            {
                StringBuffer sb = new StringBuffer(resolvedTypeSignature);

                if (sb.charAt(sb.length()-1) == ';')
                {
                    sb = sb.delete(sb.length()-1, sb.length());
                }
                
                sb.append("<"); //$NON-NLS-1$
                for(String param : typeParameters)
                {
                    //System.out.println("type param: "+resolvedType.getTypeParameter(param));
                    sb.append(param);
                }
                
                // replace the dangling ',' with the closing ">"
                sb.append(">;"); //$NON-NLS-1$
                return sb.toString();
            }
            
            return resolvedTypeSignature;
        }

        if (Signature.getTypeSignatureKind(typeSignature) == 
                Signature.CLASS_TYPE_SIGNATURE
            || Signature.getTypeSignatureKind(typeSignature)
                == Signature.TYPE_VARIABLE_SIGNATURE)
        {
            // if we are unable to resolve, check to see if the owning type has
            // a parameter by this name
            ITypeParameter typeParam = owningType.getTypeParameter(Signature.getSignatureSimpleName(typeSignature));
            
            // if we have a type parameter and it hasn't been resolved to a type,
            // then assume it is a method template placeholder (i.e. T in ArrayList).
            // at runtime these unresolved parameter variables are effectively 
            // turned into Object's.  For example, think List.add(E o).  At runtime,
            // E will behave exactly like java.lang.Object in that signature
            if (typeParam.exists())
            {
                return TypeConstants.TYPE_JAVAOBJECT;
            }
            
            // TODO: is there a better way to handle a failure to resolve
            // than just garbage out?
            //JSFCommonPlugin.log(new Exception("Failed to resolve type: "+typeSignature), "Failed to resolve type: "+typeSignature); //$NON-NLS-1$ //$NON-NLS-2$
        }
        
        return typeSignature;
    }

    private static IType resolveTypeRelative(final IType owningType, final String typeSignature)
    {
        final String fullName = getFullyQualifiedName(typeSignature);
        
        IType resolvedType = null;
        
        try
        {
            // TODO: this call is only supported on sourceTypes!
            String[][] resolved = owningType.resolveType(fullName);
    
            if (resolved != null && resolved.length > 0)
            {
                resolvedType = owningType.getJavaProject().findType(resolved[0][0], resolved[0][1]);
            }
            else
            {
                resolvedType = resolveInParents(owningType, fullName);
            }
        }
        catch (JavaModelException jme)
        {
            //  do nothing; newType == null
        }

        return resolvedType;
    }

    /**
     * @param type
     * @return a type signature for a type
     */
    public static String getSignature(IType type)
    {
        final String fullyQualifiedName = type.getFullyQualifiedName();
        return Signature.createTypeSignature(fullyQualifiedName, true);
    }

    
    /**
     * @param owner
     * @param unresolvedSignature
     * @return the resolved method signature for unresolvedSignature in owner
     */
    public static String resolveMethodSignature(final IType  owner, 
                                         final String unresolvedSignature)
    {
        // get the list of parameters
        final String[] parameters = 
            Signature.getParameterTypes(unresolvedSignature);
        
        for (int i = 0; i < parameters.length; i++)
        {
            // try to full resolve the type
            parameters[i] = resolveTypeSignature(owner, parameters[i]);
        }
        
        // resolve return type
        final String resolvedReturn = 
            resolveTypeSignature(owner, 
                                  Signature.getReturnType(unresolvedSignature));
        
        return Signature.createMethodSignature(parameters, resolvedReturn);
    }
    
    /**
     * @param typeSignature     
     * @return a fully qualified Java class name from a type signature
     * i.e. Ljava.lang.String; -> java.lang.String
     */
    public static String getFullyQualifiedName(final String typeSignature)
    {
        final String packageName = Signature.getSignatureQualifier(typeSignature);
        final String typeName = Signature.getSignatureSimpleName(typeSignature);
        return "".equals(packageName) ? typeName : packageName + "." + typeName;  //$NON-NLS-1$//$NON-NLS-2$
    }
    
    private static IType resolveInParents(IType  childType, String fullyQualifiedName)
                                throws JavaModelException
    {
        IType resolvedType = null;
        
        // not resolved? try the supertypes
        final ITypeHierarchy typeHierarchy =
            childType.newSupertypeHierarchy(new NullProgressMonitor());
        IType[] superTypes = typeHierarchy.getAllSupertypes(childType);
        String[][]   resolved;
        
        LOOP_UNTIL_FIRST_MATCH:
            for (int i = 0; i < superTypes.length; i++)
        {
            IType type = superTypes[i];
            
            // XXX: this is a partial workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=212225
            // In certain cases, unresolved type names may cause resolveType to
            // throw array out of bounds.
            try
            {
            	resolved = type.resolveType(fullyQualifiedName);
            }
            catch (ArrayIndexOutOfBoundsException ae)
            {
            	resolved = null;
            	JSFCommonPlugin.log(IStatus.WARNING, "Known issue detected.  See https://bugs.eclipse.org/bugs/show_bug.cgi?id=212225");
            }
            
            if (resolved != null && resolved.length > 0)
            {
                resolvedType = childType.getJavaProject().findType(resolved[0][0], resolved[0][1]);
                break LOOP_UNTIL_FIRST_MATCH;
            }
        }

        return resolvedType;
    }
    
    /**
     * Attempts to get a Java IType for a fully qualified signature.  Note that
     * generic type arguments are generally ignored by JDT when doing such 
     * look ups.
     * 
     * @param javaProject the project context inside which to resolve the type
     * @param fullyResolvedTypeSignature a fully resolved type signature
     * @return the IType if resolved, null otherwise
     */
    public static IType resolveType(final IJavaProject javaProject, final String fullyResolvedTypeSignature)
    {
        final String fullyQualifiedName =
            getFullyQualifiedName(fullyResolvedTypeSignature);
        
        try {
            return javaProject.findType(fullyQualifiedName);
        } catch (JavaModelException e) {
            // accessible problem
            JSFCommonPlugin.log(e);
            return null;
        }
    }
    
    /**
     * @param type
     * @param typeParamSignature -- must be a Type Variable Signature
     * @param typeArguments
     * @return the signature for the type argument in typeArguments that matches the
     * named typeParamSignature in type.
     * @throws IllegalArgumentException if typeParamSignature is not valid
     * 
     * For example, given type for java.util.Map, typeParamSignature == "V" and
     * typeArguments = {Ljava.util.String;, Lcom.test.Blah;}, the result would be
     * the typeArgument that matches "V", which is "Lcom.test.Blah;}
     * 
     * returns null if the match cannot be found.
     */
    public static String matchTypeParameterToArgument(final IType type, final String typeParamSignature, final List<String> typeArguments)
    {
    	if (Signature.getTypeSignatureKind(typeParamSignature) != Signature.TYPE_VARIABLE_SIGNATURE)
    	{
    		throw new IllegalArgumentException();
    	}
    	
        try
        {
            ITypeParameter[] typeParams = type.getTypeParameters();

            for (int pos = 0; pos < typeParams.length; pos++)
            {
                if (typeParams[pos].getElementName().equals(Signature.getSignatureSimpleName(typeParamSignature)))
                {
                    if (pos < typeArguments.size())
                    {
                        // TODO: should typeArguments.size ever != typeParams.length?
                        return typeArguments.get(pos);
                    }
                }
            }
        } 
        catch (JavaModelException e) 
        {
            JSFCommonPlugin.log(e);
        }
        
        return null;
    }
    
    /**
     * @param type
     * @param fieldName
     * @return true if fieldName is a member of type.  Note that if type is java.lang.Enum
     * then this will always return true since we cannot know what fields the instance has (it could be any enum)
     */
    public static boolean isEnumMember(final IType type, final String fieldName)
    {
        try
        {
            if (type == null || !isEnumType(type))
            {
                throw new IllegalArgumentException("type must be non-null and isEnum()==true"); //$NON-NLS-1$
            }
            
            if (fieldName == null)
            {
                throw new IllegalArgumentException("fieldName must be non-null"); //$NON-NLS-1$
            }

            // if type is the java.lang.Enum, always true
            if (TypeConstants.TYPE_ENUM_BASE.equals(Signature.createTypeSignature(type.getFullyQualifiedName(), true)))
            {
                return true;
            }
            
            final IField field = type.getField(fieldName);

            if (field.exists() && field.isEnumConstant())
            {
                return true;
            }
        }
        catch (JavaModelException jme)
        {
            // fall through and return false
        }
        
        return false;
    }
    
    /**
     * @param typeSig1 the type signature of the first enum. Must be non-null, fully resolved enum type.
     * @param typeSig2 the type signature of the second enum.  Must be non-null, fully resolved enum type.
     * 
     * @return true if typeSig1.compareTo(typeSig2) is a legal operation (won't throw a CCE)
     */
    public static boolean isEnumsCompareCompatible(final String typeSig1, final String typeSig2)
    {
        if (typeSig1 == null || typeSig2 == null)
        {
            throw new IllegalArgumentException("args must not be null"); //$NON-NLS-1$
        }
        
        if (Signature.getTypeSignatureKind(typeSig1) != Signature.CLASS_TYPE_SIGNATURE
             || Signature.getTypeSignatureKind(typeSig2) != Signature.CLASS_TYPE_SIGNATURE)
        {
            throw new IllegalArgumentException("args must be resolved class types"); //$NON-NLS-1$
        }
        
        // if one or the other is the raw enum type, then they *may* be comparable; we don't know
        if (TypeConstants.TYPE_ENUM_BASE.equals(typeSig1) 
                || TypeConstants.TYPE_ENUM_BASE.equals(typeSig2))
        {
            return true;
        }
        
        // TODO: support the case of enum base type with generic type argument
        
        // only comparable if is the same class
        return typeSig1.equals(typeSig2);
    }
    
    /**
     * @param typeSig1 the type signature of the first enum. Must be non-null, fully resolved enum type.
     * @param typeSig2 the type signature of the second enum. Must be non-null, fully resolved enum type.
     * @return true if instances typeSig1 and typeSig2 can never be equal due
     * their being definitively different enum types
     */
    public static boolean canNeverBeEqual(final String typeSig1, final String typeSig2)
    {
        if (typeSig1 == null || typeSig2 == null)
        {
            throw new IllegalArgumentException("args must not be null"); //$NON-NLS-1$
        }
        
        if (Signature.getTypeSignatureKind(typeSig1) != Signature.CLASS_TYPE_SIGNATURE
             || Signature.getTypeSignatureKind(typeSig2) != Signature.CLASS_TYPE_SIGNATURE)
        {
            throw new IllegalArgumentException("args must be resolved class types"); //$NON-NLS-1$
        }

        // if either one is the base enum type, then we can't be sure
        if (TypeConstants.TYPE_ENUM_BASE.equals(typeSig1) 
                || TypeConstants.TYPE_ENUM_BASE.equals(typeSig2))
        {
            return false;
        }

        // if they are definitely not the same enum types, then their values
        // can never be equal
        return !typeSig1.equals(typeSig2);
    }
    

    /**
     * NOTE: we diverge from IType.isEnum() because we also return true if the base type
     * is a java.lang.Enum since we consider this to be "any enumeration type" whereas JDT considers
     * it merely a class since it doesn't use an "enum" keyword declaration.
     * @param type
     * @return true if type is an enum type or is java.lang.Enum
     */
    static boolean isEnumType(IType type)
    {
        if (type == null)
        {
            return false;
        }
        
        // check if it's the enumeration base type
        if (TypeConstants.TYPE_ENUM_BASE.equals(Signature.createTypeSignature(type.getFullyQualifiedName(), true)))
        {
            return true;
        }
    
        try
        {
            return type.isEnum();
        }
        catch (JavaModelException jme)
        {
            // log and fallthrough to return false
            JSFCommonPlugin.log(jme, "Problem resolving isEnum"); //$NON-NLS-1$
        }
        
        // if unresolved assume false
        return false;
    }
    
    private TypeUtil()
    {
        // no external instantiation
    }
}
