/*******************************************************************************
 * 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.internal.types;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.jdt.core.Signature;

/**
 * Transforms one CompositeType to another according to particular 
 * transform rules.
 * 
 * In general, every transformation should be of the form:
 * 
 *   CompositeType  transform(CompositeType original, other inputs...);
 * 
 * @author cbateman
 *
 */
public class TypeTransformer 
{
    private final static Map  boxConversions = new HashMap();
    private final static Map  unBoxConversions = new HashMap();
    
    static
    {
        // see jdt.core.Signature or JVM link spec for more details
        boxConversions.put("B", "Ljava.lang.Byte;");  //$NON-NLS-1$//$NON-NLS-2$
        boxConversions.put("C", "Ljava.lang.Character;"); //$NON-NLS-1$ //$NON-NLS-2$
        boxConversions.put("D", "Ljava.lang.Double;"); //$NON-NLS-1$ //$NON-NLS-2$
        boxConversions.put("F", "Ljava.lang.Float;"); //$NON-NLS-1$ //$NON-NLS-2$
        boxConversions.put("I", "Ljava.lang.Integer;"); //$NON-NLS-1$ //$NON-NLS-2$
        boxConversions.put("J", "Ljava.lang.Long;"); //$NON-NLS-1$ //$NON-NLS-2$
        boxConversions.put("S", "Ljava.lang.Short;"); //$NON-NLS-1$ //$NON-NLS-2$
        boxConversions.put("Z", "Ljava.lang.Boolean;"); //$NON-NLS-1$ //$NON-NLS-2$
        // don't box V
        boxConversions.put("V", "V"); //$NON-NLS-1$ //$NON-NLS-2$
    
        // invert hte box conversions
        for (final Iterator it = boxConversions.keySet().iterator(); it.hasNext();)
        {
            final String newValue = (String) it.next();
            final String newKey = (String) boxConversions.get(newValue);
            if (unBoxConversions.put(newKey, newValue) != null)
            {
                // if put returns non-null then we have replaced a key
                // added on a previous iteration.  This implies
                // that box mappings are no longer one-to-one
                throw new AssertionError("Duplicated boxing value"); //$NON-NLS-1$
            }
        }
    }
    
    /**
     * @param compositeType
     * @return an equivilent form of compositeType with all primitive type
     * signatures converted to their fully qualified boxed equivilent but
     * otherwise unchanged.
     * 
     * Example:   J -> Ljava.lang.Long;
     */
    public static CompositeType transformBoxPrimitives(CompositeType compositeType)
    {
        String[] signatures = compositeType.getSignatures();
        String[] newsignatures = new String[signatures.length];
        
        for (int i = 0; i < signatures.length; i++)
        {
            newsignatures[i] = transformBoxPrimitives(signatures[i]);
        }
        
        return new CompositeType(newsignatures, compositeType.getAssignmentTypeMask());
    }
    
    /**
     * Performs boxing for a single typeSignature string
     * @param curSignature
     * @return the boxed signature
     */
    public static String transformBoxPrimitives(final String curSignature)
    {
        String newSignature = curSignature;
        
        // first determine if we have a type or method signature
        try
        {
            int kind = Signature.getTypeSignatureKind(curSignature);
            
            // interested in base types, since these need boxing
            if (kind == Signature.BASE_TYPE_SIGNATURE)
            {
                // grab the box for the primitive
                newSignature = (String) boxConversions.get(curSignature);
            }
            else if (kind == Signature.ARRAY_TYPE_SIGNATURE)
            {
                // check if it's array of primitives
                final String baseType = Signature.getElementType(curSignature);
                
                if (Signature.getTypeSignatureKind(baseType) == Signature.BASE_TYPE_SIGNATURE)
                {
                    // it is, so box it
                    final String newBaseType = (String) boxConversions.get(baseType);
                    final int numBraces = Signature.getArrayCount(curSignature);
                    newSignature = ""; //$NON-NLS-1$
                    for (int j = 0; j < numBraces; j++)
                    {
                        newSignature += "["; //$NON-NLS-1$
                    }
                    
                    newSignature += newBaseType;
                }
            }
        }
        catch (IllegalArgumentException e)
        {
            // signature was not a type signature, so must be a method sig
            // do nothing: don't box method types
        }

        return newSignature;
    }
    
    /**
     * Performs the exact inverse of transformBoxPrimitives -- takes all
     * boxing type signatures and replaces them with their primitive equivilent
     * @param compositeType
     * @return a new composite with all boxed primitives unboxed
     */
    public static CompositeType transformUnboxPrimitives(CompositeType compositeType)
    {
        String[] signatures = compositeType.getSignatures();
        String[] newsignatures = new String[signatures.length];
        
        for (int i = 0; i < signatures.length; i++)
        {
            newsignatures[i] = transformUnboxPrimitives(signatures[i]);
        }
        
        return new CompositeType(newsignatures, compositeType.getAssignmentTypeMask());
    }
    
    /**
     * Performs unboxing for a single typeSignature string
     * 
     * @param typeSignature
     * @return the transformed signature
     */
    public static String transformUnboxPrimitives(final String typeSignature)
    {
        String newSignature = typeSignature;
        
        // first determine if we have a type or method signature
        try
        {
            int kind = Signature.getTypeSignatureKind(typeSignature);
            
            // interested in class types, since these need boxing
            if (kind == Signature.CLASS_TYPE_SIGNATURE)
            {
                // grab the box for the primitive
                String checkForUnbox  = (String) unBoxConversions.get(typeSignature);
                
                if (checkForUnbox != null)
                {
                    newSignature = checkForUnbox;
                }
            }
            else if (kind == Signature.ARRAY_TYPE_SIGNATURE)
            {
                // check if it's array of objects
                final String baseType = Signature.getElementType(typeSignature);
                
                if (Signature.getTypeSignatureKind(baseType) == Signature.CLASS_TYPE_SIGNATURE)
                {
                    // it is, so unbox it
                    final String newBaseTypeCandidate = (String) unBoxConversions.get(baseType);
                    
                    if (newBaseTypeCandidate != null)
                    {
                        final int numBraces = Signature.getArrayCount(typeSignature);
                        newSignature = ""; //$NON-NLS-1$
                        for (int j = 0; j < numBraces; j++)
                        {
                            newSignature += "["; //$NON-NLS-1$
                        }
                        
                        newSignature += newBaseTypeCandidate;
                    }
                }
            }
        }
        catch (IllegalArgumentException e)
        {
            // signature was not a type signature, so must be a method sig
            // do nothing: don't box method types
        }
        
        return newSignature;
    }
}
