/*
$Id$ created on 25.10.2005

Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.

Redistribution and use of this software and associated documentation
("Software"), with or without modification, are permitted provided
that the following conditions are met:

1. Redistributions of source code must retain copyright
   statements and notices.  Redistributions must also contain a
   copy of this document.

2. Redistributions in binary form must reproduce the
   above copyright notice, this list of conditions and the
   following disclaimer in the documentation and/or other
   materials provided with the distribution.

3. The name "groovy" must not be used to endorse or promote
   products derived from this Software without prior written
   permission of The Codehaus.  For written permission,
   please contact info@codehaus.org.

4. Products derived from this Software may not be called "groovy"
   nor may "groovy" appear in their names without prior written
   permission of The Codehaus. "groovy" is a registered
   trademark of The Codehaus.

5. Due credit should be given to The Codehaus -
   http://groovy.codehaus.org/

THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.codehaus.groovy.ast;

import groovy.lang.Closure;
import groovy.lang.GString;
import groovy.lang.MetaClass;
import groovy.lang.Range;
import groovy.lang.Reference;
import groovy.lang.Script;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.objectweb.asm.Opcodes;

/**
 * This class is a Helper for ClassNode and classes handling ClassNodes.
 * It does contain a set of predefined ClassNodes for the most used 
 * types and some code for cached ClassNode creation and basic 
 * ClassNode handling 
 * 
 * @author Jochen Theodorou
 */
public class ClassHelper {
    

    private static String[] names = new String[] {
        boolean.class.getName(),    char.class.getName(), 
        byte.class.getName(),       short.class.getName(),
        int.class.getName(),        long.class.getName(),
        double.class.getName(),     float.class.getName(),
        Object.class.getName(),     Void.TYPE.getName(),
        Closure.class.getName(),    GString.class.getName(),
        List.class.getName(),       Map.class.getName(),
        Range.class.getName(),      Pattern.class.getName(),
        Script.class.getName(),     String.class.getName(),
        Boolean.class.getName(),    Character.class.getName(),
        Byte.class.getName(),       Short.class.getName(),
        Integer.class.getName(),    Long.class.getName(),
        Double.class.getName(),     Float.class.getName(),
        BigDecimal.class.getName(), BigInteger.class.getName(),
        Void.class.getName(),       Reference.class.getName(),
        Class.class.getName(),      MetaClass.class.getName()
    };
    
    private static Class[] classes = new Class[] {
        Object.class, Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE,
        Integer.TYPE, Long.TYPE, Double.TYPE, Float.TYPE, Void.TYPE,
        Closure.class, GString.class, List.class, Map.class, Range.class,
        Pattern.class, Script.class, String.class,  Boolean.class, 
        Character.class, Byte.class, Short.class, Integer.class, Long.class,
        Double.class, Float.class, BigDecimal.class, BigInteger.class, Void.class,
        Reference.class, Class.class, MetaClass.class
    };
    
    public static final ClassNode 
        DYNAMIC_TYPE = new ClassNode(Object.class),  OBJECT_TYPE = DYNAMIC_TYPE,
        VOID_TYPE = new ClassNode(Void.TYPE),        CLOSURE_TYPE = new ClassNode(Closure.class),
        GSTRING_TYPE = new ClassNode(GString.class), LIST_TYPE = new ClassNode(List.class),
        MAP_TYPE = new ClassNode(Map.class),         RANGE_TYPE = new ClassNode(Range.class),
        PATTERN_TYPE = new ClassNode(Pattern.class), STRING_TYPE = new ClassNode(String.class),
        SCRIPT_TYPE = new ClassNode(Script.class),   REFERENCE_TYPE = new ClassNode(Reference.class),
        
        boolean_TYPE = new ClassNode(boolean.class),     char_TYPE = new ClassNode(char.class),
        byte_TYPE = new ClassNode(byte.class),           int_TYPE = new ClassNode(int.class),
        long_TYPE = new ClassNode(long.class),           short_TYPE = new ClassNode(short.class),
        double_TYPE = new ClassNode(double.class),       float_TYPE = new ClassNode(float.class),
        Byte_TYPE = new ClassNode(Byte.class),           Short_TYPE = new ClassNode(Short.class),
        Integer_TYPE = new ClassNode(Integer.class),     Long_TYPE = new ClassNode(Long.class),
        Character_TYPE = new ClassNode(Character.class), Float_TYPE = new ClassNode(Float.class),
        Double_TYPE = new ClassNode(Double.class),       Boolean_TYPE = new ClassNode(Boolean.class),
        BigInteger_TYPE =  new ClassNode(java.math.BigInteger.class),
        BigDecimal_TYPE = new ClassNode(java.math.BigDecimal.class),
        void_WRAPPER_TYPE = new ClassNode(Void.class),   
        
        CLASS_Type = new ClassNode(Class.class),        METACLASS_TYPE = new ClassNode(MetaClass.class);
        
    
    private static ClassNode[] types = new ClassNode[] {
        OBJECT_TYPE,
        boolean_TYPE, char_TYPE, byte_TYPE, short_TYPE,
        int_TYPE, long_TYPE, double_TYPE, float_TYPE,
        VOID_TYPE, CLOSURE_TYPE, GSTRING_TYPE,
        LIST_TYPE, MAP_TYPE, RANGE_TYPE, PATTERN_TYPE,
        SCRIPT_TYPE, STRING_TYPE, Boolean_TYPE, Character_TYPE,
        Byte_TYPE, Short_TYPE, Integer_TYPE, Long_TYPE,
        Double_TYPE, Float_TYPE, BigDecimal_TYPE, BigInteger_TYPE, 
        void_WRAPPER_TYPE, REFERENCE_TYPE, CLASS_Type, METACLASS_TYPE
    };

    
    private static ClassNode[] numbers = new ClassNode[] {
        char_TYPE, byte_TYPE, short_TYPE, int_TYPE, long_TYPE, 
        double_TYPE, float_TYPE, Short_TYPE, Byte_TYPE, Character_TYPE,
        Integer_TYPE, Float_TYPE, Long_TYPE, Double_TYPE, BigInteger_TYPE,
        BigDecimal_TYPE
    };

    protected static final ClassNode[] EMPTY_TYPE_ARRAY = {};
    
    public static final String OBJECT = "java.lang.Object";    
    
    
    /**
     * Creates an array of ClassNodes using an array of classes.
     * For each of the given classes a new ClassNode will be 
     * created
     * @see #make(Class)
     * @param classes an array of classes used to create the ClassNodes
     * @return an array of ClassNodes
     */
    public static ClassNode[] make(Class[] classes) {
    	ClassNode[] cns = new ClassNode[classes.length];
    	for (int i=0; i<cns.length; i++) {
    		cns[i] = make(classes[i]);
    	}
    	
    	return cns;
    }
    
    /**
     * Creates a ClassNode using a given class.
     * A new ClassNode object is only created if the class
     * is not one of the predefined ones
     * 
     * @param c class used to created the ClassNode
     * @return ClassNode instance created from the given class
     */
    public static ClassNode make(Class c) {
        for (int i=0; i<classes.length; i++) {
            if (c==classes[i]) return types[i];
        }
        if (c.isArray()) {
            ClassNode cn = make(c.getComponentType());
            return cn.makeArray();
        }
        ClassNode t = new ClassNode(c);
        return t;
    }
    
    /**
     * Creates a ClassNode using a given class.
     * Unlike make(String) this method will not use the cache
     * to create the ClassNode. This means the ClassNode created
     * from this method using the same name will have a different
     * references
     * 
     * @see #make(String)
     * @param name of the class the ClassNode is representing
     */
    public static ClassNode makeWithoutCaching(String name) { 
        ClassNode cn = new ClassNode(name,Opcodes.ACC_PUBLIC,OBJECT_TYPE);
        cn.isPrimaryNode = false;
        return cn;
    }
    
    /**
     * Creates a ClassNode using a given class.
     * If the name is one of the predefined ClassNodes then the 
     * corresponding ClassNode instance will be returned. If the
     * is null of of length 0 the dynamic type is returned
     * 
     * @param name of the class the ClassNode is representing
     */
    public static ClassNode make(String name) {
        if (name == null || name.length() == 0) return DYNAMIC_TYPE;
        
        for (int i=0; i<classes.length; i++) {
            String cname = classes[i].getName();
            if (name.equals(cname)) return types[i];
        }        
        return makeWithoutCaching(name);
    }
    
    /**
     * Creates a ClassNode containing the wrapper of a ClassNode 
     * of primitive type. Any ClassNode representing a primitive
     * type should be created using the predefined types used in
     * class. The method will check the parameter for known 
     * references of ClassNode representing a primitive type. If
     * Reference is found, then a ClassNode will be contained that
     * represents the wrapper class. For exmaple for boolean, the 
     * wrapper class is java.lang.Boolean.
     * 
     * If the parameter is no primitve type, the redirected 
     * ClassNode will be returned 
     *   
     * @see #make(Class)
     * @see #make(String)
     * @param cn the ClassNode containing a possible primitive type
     */
    public static ClassNode getWrapper(ClassNode cn) {
        cn = cn.redirect();
        if (!isPrimitiveType(cn)) return cn;
        if (cn==boolean_TYPE) {
            return Boolean_TYPE;
        } else if (cn==byte_TYPE) {
            return Byte_TYPE;
        } else if (cn==char_TYPE) {
            return Character_TYPE;
        } else if (cn==short_TYPE) {
            return Short_TYPE;
        } else if (cn==int_TYPE) {
            return Integer_TYPE;
        } else if (cn==long_TYPE) {
            return Long_TYPE;
        } else if (cn==float_TYPE) {
            return Float_TYPE;
        } else if (cn==double_TYPE) {
            return Double_TYPE;
        } else if (cn==VOID_TYPE) {
        	return void_WRAPPER_TYPE;
        }
        else {
            return cn;
        }
    }
    
    /**
     * Test to determine if a ClasNode is a primitve type. 
     * Note: this only works for ClassNodes created using a
     * predefined ClassNode
     * 
     * @see #make(Class)
     * @see #make(String)
     * @param cn the ClassNode containing a possible primitive type
     * @return true if the ClassNode is a primitve type
     */
    public static boolean isPrimitiveType(ClassNode cn) {
        return  cn == boolean_TYPE ||
                cn == char_TYPE ||
                cn == byte_TYPE ||
                cn == short_TYPE ||
                cn == int_TYPE ||
                cn == long_TYPE ||
                cn == float_TYPE ||
                cn == double_TYPE ||
                cn == VOID_TYPE;
    }

    public static ClassNode makeReference() {
        return make(Reference.class);
    }

}
