/*******************************************************************************
 * Copyright (c) 2005, 2008 BEA Systems, Inc.
 * 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:
 *    tyeung@bea.com - initial API and implementation
 *******************************************************************************/

package org.eclipse.jdt.apt.core.internal.util;

import com.sun.mirror.declaration.TypeDeclaration;
import com.sun.mirror.declaration.TypeParameterDeclaration;
import com.sun.mirror.type.ArrayType;
import com.sun.mirror.type.DeclaredType;
import com.sun.mirror.type.PrimitiveType;
import com.sun.mirror.type.ReferenceType;
import com.sun.mirror.type.TypeMirror;
import com.sun.mirror.type.TypeVariable;
import com.sun.mirror.type.VoidType;
import com.sun.mirror.type.WildcardType;
import com.sun.mirror.util.Types;
import java.util.Collection;

import org.eclipse.jdt.apt.core.internal.NonEclipseImplementationException;
import org.eclipse.jdt.apt.core.internal.declaration.*;
import org.eclipse.jdt.apt.core.internal.env.BaseProcessorEnv;
import org.eclipse.jdt.apt.core.internal.type.ArrayTypeImpl;
import org.eclipse.jdt.core.BindingKey;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.dom.ITypeBinding;

public class TypesUtil implements Types
{	
	private static final String[] NO_ARGS = new String[0];
    private final BaseProcessorEnv _env;
	
	public static void main(String[] args){}

    public TypesUtil(BaseProcessorEnv env){
        _env = env;
        assert env != null : "null environment."; //$NON-NLS-1$
    }
    
    public ArrayType getArrayType(TypeMirror componentType)
    {
        if( componentType == null ) return null;
        if( componentType instanceof EclipseMirrorType ){
            final EclipseMirrorType impl = (EclipseMirrorType)componentType;
            // the leaf type of the array
            final ITypeBinding leaf;
            final int dimension;
            switch( impl.kind() )
            {
                case TYPE_ERROR: case TYPE_VOID:
                    throw new IllegalArgumentException("Illegal element type for array"); //$NON-NLS-1$
                case TYPE_ARRAY:
                    final ITypeBinding array = ((ArrayTypeImpl)componentType).getTypeBinding();
                    dimension = array.getDimensions() + 1;
                    leaf = array.getElementType();
                    break;
                default:
                    leaf = impl.getTypeBinding();
                    dimension = 1;
                    break;
            }
            if( leaf == null || leaf.isParameterizedType() )
                throw new IllegalArgumentException("illegal component type: " + componentType); //$NON-NLS-1$

            final String bindingKey = BindingKey.createArrayTypeBindingKey(leaf.getKey(), dimension);
			final ITypeBinding arrayType = _env.getTypeBindingFromKey(bindingKey);
			if(arrayType == null)
				return null;
			return (ArrayType)Factory.createTypeMirror(arrayType, _env); 
        }
		
        throw new NonEclipseImplementationException("only applicable to eclipse type system objects." + //$NON-NLS-1$
                                                    " Found " + componentType.getClass().getName()); //$NON-NLS-1$
                                                
    }

    /**
     * @param outer a type
     * @param inner the simple name of the nested class
     * @return the binding that correspond to <code>outer.getQualifiedName()</code>.<code>inner</code>
     * 		   or null if it cannot be located.
     */
    private ITypeBinding findMemberType(ITypeBinding outer, String inner )
    {
        if( outer == null || inner == null ) return null;        

        outer = outer.getTypeDeclaration();        

        final ITypeBinding[] nestedTypes = outer.getDeclaredTypes();
        // first we search throw the ones that are directly declared within 'outer'
        for( ITypeBinding nestedType : nestedTypes ){
            if( inner.equals(nestedType.getName()) )
                return nestedType;
        }
		// then we look up the hierachy chain.
		// first we search the super type
		ITypeBinding result = findMemberType(outer.getSuperclass(), inner);
		if( result != null ) return result;
		
		// then the super interfaces
		final ITypeBinding[] interfaces = outer.getInterfaces();
		for( ITypeBinding interfaceType : interfaces ){
			result = findMemberType(interfaceType, inner);
			if( result != null ) return result;
		}
        
		// can't find it.
		return null;
    }

    public com.sun.mirror.type.DeclaredType getDeclaredType(DeclaredType containing, TypeDeclaration decl, TypeMirror... typeArgs)
    {
		if( decl == null ) return null;
	
        final ITypeBinding outerBinding = getTypeBinding(containing);
		final ITypeBinding memberBinding;
		
		if( containing == null )
			memberBinding = getTypeBinding(decl);
		else{
			if( outerBinding.isGenericType() )
	             throw new IllegalArgumentException("[containing], " + containing + ", is a generic type."); //$NON-NLS-1$ //$NON-NLS-2$
			 // make sure 'decl' is a valid member of 'outerBinding'
			memberBinding = findMemberType(outerBinding, decl.getSimpleName() );
			if( memberBinding == null )        
	            throw new IllegalArgumentException(decl + " is not a member type of " + containing ); //$NON-NLS-1$
		}
		
		final int numArgs = typeArgs == null ? 0 : typeArgs.length;		
		
		if( memberBinding.isGenericType() ){
			final String[] argKeys = numArgs == 0 ? NO_ARGS : new String[numArgs];
			for( int i=0; i<numArgs; i++ ){		
				final ITypeBinding binding = getTypeBinding(typeArgs[i]);
				assert binding != null : "failed to get binding mirror type"; //$NON-NLS-1$
				argKeys[i] = binding.getKey();
			}
			
			final ITypeBinding[] typeParams = memberBinding.getTypeParameters();
			final int numTypeParams = typeParams == null ? 0 : typeParams.length;
			// if no argument then a raw type will be created, otherwise it's an error when the 
			// number of type parameter and arguments don't agree.
			if( numTypeParams != numArgs && numArgs != 0 )
				throw new IllegalArgumentException("type, " + memberBinding.getQualifiedName() + ", require " + numTypeParams + " type arguments " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                        "but found " + numArgs ); //$NON-NLS-1$
			
			final String typeKey = BindingKey.createParameterizedTypeBindingKey(memberBinding.getKey(), argKeys);
			final ITypeBinding resultBinding = _env.getTypeBindingFromKey(typeKey);
			return Factory.createReferenceType(resultBinding, _env);
		}
		else{ 
			if( numArgs != 0 )
				throw new IllegalArgumentException("type, " + memberBinding + " is not a generic type and cannot have type arguments."); //$NON-NLS-1$ //$NON-NLS-2$
			// simple case, turning a non-generic TypeDeclaration into a DeclaredType
			return (DeclaredType)decl;
		}	
    }

    public com.sun.mirror.type.DeclaredType getDeclaredType(TypeDeclaration decl, TypeMirror... typeArgs)
    {
		return getDeclaredType(null, decl, typeArgs);		
    }

    public TypeMirror getErasure(TypeMirror t)
    {	
        if( t == null ) return null;
        
        if(t instanceof EclipseMirrorType){
            final EclipseMirrorType impl = (EclipseMirrorType)t;
            final ITypeBinding binding;
            switch( impl.kind() )
            {
                case TYPE_PRIMITIVE:
                case TYPE_VOID:
                case TYPE_ERROR:
                    return t;
                
                default:
                    binding = impl.getTypeBinding();
            }
            final ITypeBinding erasure = binding.getErasure();
            if( erasure == binding ) return t;
            TypeMirror m_erasure = Factory.createTypeMirror(erasure, impl.getEnvironment() );
            if( m_erasure == null )
                return Factory.createErrorClassType(erasure);
            return m_erasure;
        }

        throw new NonEclipseImplementationException("only applicable to eclipse type system objects." + //$NON-NLS-1$
                                                    " Found " + t.getClass().getName());	 //$NON-NLS-1$
	}

    public PrimitiveType getPrimitiveType(PrimitiveType.Kind kind)
    {
        if( kind == null ) return null;
        switch(kind)
        {
            case BOOLEAN: return _env.getBooleanType();
            case BYTE:    return _env.getByteType();
            case CHAR:    return _env.getCharType();
            case DOUBLE:  return _env.getDoubleType();
            case FLOAT:   return _env.getFloatType();
            case INT:     return _env.getIntType();
            case LONG:    return _env.getLongType();
            case SHORT:   return _env.getShortType();
          
            default: throw new IllegalStateException("unknown primitive kind : " + kind); //$NON-NLS-1$
        }
    }

    public TypeVariable getTypeVariable(TypeParameterDeclaration tparam)
    {
        if( tparam == null ) return null;
        if( tparam instanceof TypeParameterDeclarationImpl)
            return (TypeVariable) tparam;

        throw new NonEclipseImplementationException("only applicable to eclipse type system objects." + //$NON-NLS-1$
                                                    " Found " + tparam.getClass().getName()); //$NON-NLS-1$
    }

    public VoidType getVoidType()
    {
        return _env.getVoidType();
    }

    public WildcardType getWildcardType(Collection<ReferenceType> upperBounds, Collection<ReferenceType> lowerBounds)
    {		
        final String boundKey;
        final char boundKind;
        final int upperBoundCount = upperBounds == null ? 0 : upperBounds.size();
        final int lowerBoundCount = lowerBounds == null ? 0 : lowerBounds.size();
        if( upperBoundCount == 0  && lowerBoundCount == 0 ){
			boundKey = null;
            boundKind = Signature.C_STAR;
        }
        else if( upperBoundCount == 1 && lowerBoundCount == 0){
			final ITypeBinding binding = getTypeBinding(upperBounds.iterator().next());
			boundKey = binding.getKey();
            boundKind = Signature.C_EXTENDS;
        }
        else if(lowerBoundCount == 1 && upperBoundCount == 0){
			final ITypeBinding binding = getTypeBinding(lowerBounds.iterator().next());
			boundKey = binding.getKey();
            boundKind = Signature.C_SUPER;
        }
        else
            throw new IllegalArgumentException("Wildcard can only have a upper bound, a lower bound or be unbounded."); //$NON-NLS-1$

		final String wildcardkey = BindingKey.createWilcardTypeBindingKey(boundKey, boundKind);
		final ITypeBinding wildcard = _env.getTypeBindingFromKey(wildcardkey);
        return (WildcardType)Factory.createTypeMirror(wildcard, _env);
    }

    /**
     * @return true iff t2 = t1 does not require explicit casting and not cause an error.
     */
    public boolean isAssignable(TypeMirror t1, TypeMirror t2)
    {
    	EclipseMirrorType left = (EclipseMirrorType)t1;
    	EclipseMirrorType right = (EclipseMirrorType)t2;
    	return left.isAssignmentCompatible(right);
    	
    }

    public boolean isSubtype(TypeMirror t1, TypeMirror t2)
    {
    	EclipseMirrorType left = (EclipseMirrorType)t1;
    	EclipseMirrorType right = (EclipseMirrorType)t2;
    	
    	return left.isSubTypeCompatible(right);
    }
    
    /**
     * @return the binding correspond to the given type.
     *         Return null if the type is an error marker.
     * @throws NonEclipseImplementationException
     */

    private static ITypeBinding getTypeBinding(TypeMirror type)
        throws NonEclipseImplementationException
    {	
        if(type == null ) return null;
        if( type instanceof EclipseMirrorType ){
            return ((EclipseMirrorType)type).getTypeBinding();
        }

        throw new NonEclipseImplementationException("only applicable to eclipse type system objects." + //$NON-NLS-1$
                                                    " Found " + type.getClass().getName()); //$NON-NLS-1$
    }

    /**
     * @return the binding correspond to the given type.
     * @throws NonEclipseImplementationException
     */
    public static ITypeBinding getTypeBinding(TypeDeclaration type)
        throws NonEclipseImplementationException
    {
        if(type == null ) return null;
        if( type instanceof EclipseMirrorObject ){           
            return ((TypeDeclarationImpl)type).getTypeBinding();
        }
        throw new NonEclipseImplementationException("only applicable to eclipse type system objects." + //$NON-NLS-1$
                                                    " Found " + type.getClass().getName()); //$NON-NLS-1$
    } 
}
