/*******************************************************************************
 * 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.jdt.core.IField;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
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;
import org.eclipse.jst.jsf.common.internal.types.TypeInfoCache;

/**
 * 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)
    {
        
        final String unresolvedSignatureNormalized =
            unresolvedSignature.replaceAll("/", "."); //$NON-NLS-1$ //$NON-NLS-2$
        
        // get the list of parameters
        final String[] parameters = 
            Signature.getParameterTypes(unresolvedSignatureNormalized);
        
        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(unresolvedSignatureNormalized));
        
        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;

        final TypeInfoCache typeInfoCache = TypeInfoCache.getInstance();
        IType[] superTypes = typeInfoCache.getCachedSupertypes(childType);
        if (superTypes == null) {
        	superTypes = typeInfoCache.cacheSupertypesFor(childType);
        }
        
        String[][]   resolved;
        
        LOOP_UNTIL_FIRST_MATCH:
            for (int i = 0; i < superTypes.length; i++)
        {
            final IType type = superTypes[i];

            resolved = type.resolveType(fullyQualifiedName);

            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)
    {
        String fullyQualifiedName = getFullyQualifiedName(fullyResolvedTypeSignature);
        fullyQualifiedName = Signature.getTypeErasure(fullyQualifiedName);
        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
    }
}
