/* GenericSignatureParser.java
   Copyright (C) 2005
   Free Software Foundation

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package gnu.java.lang.reflect;

import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Arrays;

final class TypeVariableImpl extends TypeImpl implements TypeVariable
{
    private GenericDeclaration decl;
    private Type[] bounds;
    private String name;

    TypeVariableImpl(GenericDeclaration decl, Type[] bounds, String name)
    {
        this.decl = decl;
        this.bounds = bounds;
        this.name = name;
    }

    Type resolve()
    {
        return this;
    }

    /* FIXME[GENERICS]: Remove cast */
    public Type[] getBounds()
    {
        resolve(bounds);
        return (Type[]) bounds.clone();
    }

    public GenericDeclaration getGenericDeclaration()
    {
        return decl;
    }

    public String getName()
    {
        return name;
    }

    public boolean equals(Object obj)
    {
        if (obj instanceof TypeVariableImpl)
        {
            TypeVariableImpl other = (TypeVariableImpl)obj;
            return decl.equals(other.decl) && name.equals(other.name);
        }
        return false;
    }

    public int hashCode()
    {
        return 0x5f4d5156 ^ decl.hashCode() ^ name.hashCode();
    }

    public String toString()
    {
        return name;
    }
}

final class ParameterizedTypeImpl extends TypeImpl implements ParameterizedType
{
    private String rawTypeName;
    private ClassLoader loader;
    private Class rawType;
    private Type owner;
    private Type[] typeArgs;

    ParameterizedTypeImpl(String rawTypeName, ClassLoader loader, Type owner,
        Type[] typeArgs)
    {
        this.rawTypeName = rawTypeName;
        this.loader = loader;
        this.owner = owner;
        this.typeArgs = typeArgs;
    }

    Type resolve()
    {
        if (rawType == null)
        {
            try
            {
                rawType = Class.forName(rawTypeName, false, loader);
            }
            catch (ClassNotFoundException x)
            {
                throw new TypeNotPresentException(rawTypeName, x);
            }
        }
        if (typeArgs == null)
        {
            if (owner == null)
            {
                return rawType;
            }
            typeArgs = new Type[0];
        }
        resolve(typeArgs);
        owner = resolve(owner);
        return this;
    }

    /* FIXME[GENERICS]: Remove cast */
    public Type[] getActualTypeArguments()
    {
        return (Type[]) typeArgs.clone();
    }

    public Type getRawType()
    {
        return rawType;
    }

    public Type getOwnerType()
    {
        return owner;
    }

    public boolean equals(Object obj)
    {
        if (obj instanceof ParameterizedTypeImpl)
        {
            ParameterizedTypeImpl other = (ParameterizedTypeImpl)obj;
            return rawType.equals(other.rawType)
                && ((owner == null && other.owner == null)
                    || owner.equals(other.owner))
                && Arrays.deepEquals(typeArgs, other.typeArgs);
        }
        return false;
    }

    public int hashCode()
    {
        int h = 0x58158970 ^ rawType.hashCode();
        if (owner != null)
        {
            h ^= Integer.reverse(owner.hashCode());
        }
        for (int i = 0; i < typeArgs.length; i++)
        {
            h ^= Integer.rotateLeft(typeArgs[i].hashCode(), i);
        }
        return h;
    }

    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        if (owner != null)
        {
            sb.append(owner);
            sb.append('.');
            sb.append(rawType.getSimpleName());
        }
        else
        {
            sb.append(rawTypeName);
        }
        if (typeArgs.length > 0)
        {
            sb.append('<');
            for (int i = 0; i < typeArgs.length; i++)
            {
                if (i > 0)
                    sb.append(", ");
                if (typeArgs[i] instanceof Class)
                {
                    sb.append(((Class)typeArgs[i]).getName());
                }
                else
                {
                    sb.append(typeArgs[i]);
                }
            }
            sb.append('>');
        }
        return sb.toString();
    }
}

final class GenericArrayTypeImpl extends TypeImpl implements GenericArrayType
{
    private Type componentType;

    GenericArrayTypeImpl(Type componentType)
    {
        this.componentType = componentType;
    }

    Type resolve()
    {
        componentType = resolve(componentType);
        return this;
    }

    public Type getGenericComponentType()
    {
        return componentType;
    }

    public boolean equals(Object obj)
    {
        if (obj instanceof GenericArrayTypeImpl)
        {
            GenericArrayTypeImpl other = (GenericArrayTypeImpl)obj;
            return componentType.equals(other.componentType);
        }
        return false;
    }

    public int hashCode()
    {
        return 0x4be37a7f ^ componentType.hashCode();
    }

    public String toString()
    {
        return componentType + "[]";
    }
}

final class UnresolvedTypeVariable extends TypeImpl implements Type
{
    private GenericDeclaration decl;
    private String name;

    UnresolvedTypeVariable(GenericDeclaration decl, String name)
    {
        this.decl = decl;
        this.name = name;
    }

    Type resolve()
    {
        GenericDeclaration d = decl;
        while (d != null)
        {
	    TypeVariable[] vars = d.getTypeParameters();
            for (int a = 0; a < vars.length  ; ++a)
            {
                if (vars[a].getName().equals(name))
                {
                    return vars[a];
                }
            }
            d = getParent(d);
        }
        throw new MalformedParameterizedTypeException();
    }

    private static GenericDeclaration getParent(GenericDeclaration d)
    {
        if (d instanceof Class)
        {
            Method m = ((Class)d).getEnclosingMethod();
            if (m != null)
            {
                return m;
            }
            Constructor c = ((Class)d).getEnclosingConstructor();
            if (c != null)
            {
                return c;
            }
            return ((Class)d).getEnclosingClass();
        }
        else if (d instanceof Method)
        {
            return ((Method)d).getDeclaringClass();
        }
        else if (d instanceof Constructor)
        {
            return ((Constructor)d).getDeclaringClass();
        }
        else
        {
            // TODO figure out what this represents
            throw new Error();
        }
    }
}

final class WildcardTypeImpl extends TypeImpl implements WildcardType
{
    private Type lower;
    private Type upper;

    WildcardTypeImpl(Type lower, Type upper)
    {
        this.lower = lower;
        this.upper = upper;
    }

    Type resolve()
    {
        upper = resolve(upper);
        lower = resolve(lower);
        return this;
    }

    public Type[] getUpperBounds()
    {
        if (upper == null)
        {
            return new Type[0];
        }
        return new Type[] { upper };
    }

    public Type[] getLowerBounds()
    {
        if (lower == null)
        {
            return new Type[0];
        }
        return new Type[] { lower };
    }

    public boolean equals(Object obj)
    {
        if (obj instanceof WildcardTypeImpl)
        {
            WildcardTypeImpl other = (WildcardTypeImpl)obj;
            return Arrays.deepEquals(getUpperBounds(), other.getUpperBounds())
                && Arrays.deepEquals(getLowerBounds(), other.getLowerBounds());
        }
        return false;
    }

    public int hashCode()
    {
        int h = 0x75d074fd;
        if (upper != null)
        {
            h ^= upper.hashCode();
        }
        if (lower != null)
        {
            h ^= lower.hashCode();
        }
        return h;
    }

    public String toString()
    {
        if (lower != null)
        {
            return "? super " + lower;
        }
        if (upper == java.lang.Object.class)
        {
            return "?";
        }
        return "? extends " + upper;
    }
}

class GenericSignatureParser
{
    private ClassLoader loader;
    private GenericDeclaration container;
    private String signature;
    private int pos;

    GenericSignatureParser(GenericDeclaration container, ClassLoader loader,
        String signature)
    {
        this.container = container;
        this.loader = loader;
        this.signature = signature;
    }

    TypeVariable[] readFormalTypeParameters()
    {
        consume('<');
        ArrayList params = new ArrayList();
        do
        {
            // TODO should we handle name clashes?
            params.add(readFormalTypeParameter());
        } while (peekChar() != '>');
        consume('>');
        TypeVariable[] list = new TypeVariable[params.size()];
        params.toArray(list);
        return list;
    }

    private TypeVariable readFormalTypeParameter()
    {
        String identifier = readIdentifier();
        consume(':');
        ArrayList bounds = new ArrayList();
        if (peekChar() != ':')
        {
            bounds.add(readFieldTypeSignature());
        }
        while (peekChar() == ':')
        {
            consume(':');
            bounds.add(readFieldTypeSignature());
        }
        Type[] b = new Type[bounds.size()];
        bounds.toArray(b);
        return new TypeVariableImpl(container, b, identifier);
    }

    Type readFieldTypeSignature()
    {
        switch (peekChar())
        {
            case 'L':
                return readClassTypeSignature();
            case '[':
                return readArrayTypeSignature();
            case 'T':
                return readTypeVariableSignature();
            default:
                throw new GenericSignatureFormatError();
        }
    }

    Type readClassTypeSignature()
    {
        consume('L');
        String className = "";
        for (;;)
        {
            String part = readIdentifier();
            if (peekChar() != '/')
            {
                className += part;
                break;
            }
            consume('/');
            className += part + ".";
        }
        Type[] typeArguments = null;
        if (peekChar() == '<')
        {
            typeArguments = readTypeArguments();
        }
        Type type = new ParameterizedTypeImpl(className, loader, null,
                                              typeArguments);
        while (peekChar() == '.')
        {
            consume('.');
            className += "$" + readIdentifier();
            typeArguments = null;
            if (peekChar() == '<')
            {
                typeArguments = readTypeArguments();
            }
            type = new ParameterizedTypeImpl(className, loader, type,
                                             typeArguments);
        }
        consume(';');
        return type;
    }

    private Type[] readTypeArguments()
    {
        consume('<');
        ArrayList list = new ArrayList();
        do
        {
            list.add(readTypeArgument());
        } while ((peekChar() != '>'));
        consume('>');
        Type[] arr = new Type[list.size()];
        list.toArray(arr);
        return arr;
    }

    private Type readTypeArgument()
    {
        char c = peekChar();
        if (c == '+')
        {
            consume('+');
            return new WildcardTypeImpl(null, readFieldTypeSignature());
        }
        else if (c == '-')
        {
            consume('-');
            return new WildcardTypeImpl(readFieldTypeSignature(),
                java.lang.Object.class);
        }
        else if (c == '*')
        {
            consume('*');
            return new WildcardTypeImpl(null, java.lang.Object.class);
        }
        else
        {
            return readFieldTypeSignature();
        }
    }

    Type readArrayTypeSignature()
    {
        consume('[');
        switch (peekChar())
        {
            case 'L':
            case '[':
            case 'T':
                return new GenericArrayTypeImpl(readFieldTypeSignature());
            case 'Z':
                consume('Z');
                return boolean[].class;
            case 'B':
                consume('B');
                return byte[].class;
            case 'S':
                consume('S');
                return short[].class;
            case 'C':
                consume('C');
                return char[].class;
            case 'I':
                consume('I');
                return int[].class;
            case 'F':
                consume('F');
                return float[].class;
            case 'J':
                consume('J');
                return long[].class;
            case 'D':
                consume('D');
                return double[].class;
            default:
                throw new GenericSignatureFormatError();
        }
    }

    Type readTypeVariableSignature()
    {
        consume('T');
        String identifier = readIdentifier();
        consume(';');
        return new UnresolvedTypeVariable(container, identifier);
    }

    private String readIdentifier()
    {
        int start = pos;
        char c;
        do
        {
            readChar();
            c = peekChar();
        } while (";:./<>-+*".indexOf(c) == -1);
        return signature.substring(start, pos);
    }

    final char peekChar()
    {
        if (pos == signature.length())
            return '\u0000';
        else
            return signature.charAt(pos);
    }

    final char readChar()
    {
        return signature.charAt(pos++);
    }

    final void consume(char c)
    {
        if (readChar() != c)
            throw new GenericSignatureFormatError();
    }

    final void end()
    {
        if (pos != signature.length())
            throw new GenericSignatureFormatError();
    }
}
