/*
 * Copyright 2003-2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.codehaus.groovy.runtime.typehandling;

import groovy.lang.GString;
import groovy.lang.GroovyRuntimeException;
import org.codehaus.groovy.reflection.ReflectionCache;
import org.codehaus.groovy.runtime.*;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.regex.Matcher;

public class DefaultTypeTransformation {
    
    protected static final Object[] EMPTY_ARGUMENTS = {};
    protected static final BigInteger ONE_NEG = new BigInteger("-1");
    
    //  --------------------------------------------------------
    //                  unboxing methods
    //  --------------------------------------------------------       
    
    public static byte byteUnbox(Object value) {
        Number n = castToNumber(value);
        return n.byteValue();
    }

    public static char charUnbox(Object value) {
        return castToChar(value);
    }

    public static short shortUnbox(Object value) {
        Number n = castToNumber(value);
        return n.shortValue();
    }

    public static int intUnbox(Object value) {
        Number n = castToNumber(value);
        return n.intValue();
    }

    public static boolean booleanUnbox(Object value) {
        return castToBoolean(value);
    }

    public static long longUnbox(Object value) {
        Number n = castToNumber(value);
        return n.longValue();
    }

    public static float floatUnbox(Object value) {
        Number n = castToNumber(value);
        return n.floatValue();
    }

    public static double doubleUnbox(Object value) {
        Number n = castToNumber(value);
        return n.doubleValue();
    } 

    //  --------------------------------------------------------
    //                  boxing methods
    //  --------------------------------------------------------       
    
    public static Object box(boolean value) {
        return value ? Boolean.TRUE : Boolean.FALSE;
    }

    public static Object box(byte value) {
        return new Byte(value);
    }

    public static Object box(char value) {
        return new Character(value);
    }

    public static Object box(short value) {
        return new Short(value);
    }

    public static Object box(int value) {
        return IntegerCache.integerValue(value);
    }

    public static Object box(long value) {
        return new Long(value);
    }

    public static Object box(float value) {
        return new Float(value);
    }

    public static Object box(double value) {
        return new Double(value);
    }
    
    public static Number castToNumber(Object object) {
        if (object instanceof Number) return (Number) object;
        if (object instanceof Character) {
            return new Integer(((Character) object).charValue());
        } else if (object instanceof String) {
            String c = (String) object;
            if (c.length() == 1) {
                return new Integer(c.charAt(0));
            }
            else {
                throw new GroovyCastException(c,Integer.class);
            }
        }
        throw new GroovyCastException(object,Number.class);
    }
    
    public static boolean castToBoolean(Object object) {
    	if (object == null) {
    		return false;
    	}
    	else if (object instanceof Boolean) {
            Boolean booleanValue = (Boolean) object;
            return booleanValue.booleanValue();
        }
        else if (object instanceof Matcher) {
            Matcher matcher = (Matcher) object;
            RegexSupport.setLastMatcher(matcher);
            return matcher.find();
        }
        else if (object instanceof Collection) {
            Collection collection = (Collection) object;
            return !collection.isEmpty();
        }
        else if (object instanceof Map) {
            Map map = (Map) object;
            return !map.isEmpty();
        }
        else if (object instanceof CharSequence) {
        	CharSequence string =  (CharSequence) object;
            return string.length() > 0;
        } 
        else if (object instanceof Object[]) {
        	Object[] array =  (Object[]) object;
            return array.length > 0;
        } 
        else if (object instanceof Character) {
            Character c = (Character) object;
            return c.charValue() != 0;
        }
        else if (object instanceof Number) {
            Number n = (Number) object;
            return n.doubleValue() != 0;
        }
        else {
            return true;
        }
    }
    
    public static char castToChar(Object object) {
        if (object instanceof Character) {
            return ((Character) object).charValue();            
        } else if (object instanceof Number) {
            Number value = (Number) object;
            return (char) value.intValue();
        } else {
            String text = object.toString();
            if (text.length() == 1) {
                return text.charAt(0);
            }
            else {
                throw new GroovyCastException(text,char.class);
            }
        }
    }
    
    public static Object castToType(Object object, Class type) {
        if (object == null) {
            return null;
        }
        
        if (type == object.getClass()) return object;
        // TODO we should move these methods to groovy method, like g$asType() so that
        // we can use operator overloading to customize on a per-type basis
        if (ReflectionCache.isArray(type)) {
            return asArray(object, type);

        }
        if (ReflectionCache.isAssignableFrom(type,object.getClass())) {
            return object;
        }
        if (Collection.class.isAssignableFrom(type)) {
            int modifiers = type.getModifiers();
            Collection answer;
            if (object instanceof Collection && type.isAssignableFrom(HashSet.class) &&
                    (type == HashSet.class || Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers))) {
                return new HashSet((Collection)object);
            }
            if (object.getClass().isArray()) {
                if (type.isAssignableFrom(ArrayList.class) && (Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers))) {
                    answer = new ArrayList();
                } else {
                    // lets call the collections constructor
                    // passing in the list wrapper
                    try {
                        answer = (Collection) type.newInstance();
                    }
                    catch (Exception e) {
                        throw new GroovyCastException("Could not instantiate instance of: " + type.getName() + ". Reason: " + e);
                    }
                }

                // we cannot just wrap in a List as we support primitive type arrays
                int length = Array.getLength(object);
                for (int i = 0; i < length; i++) {
                    Object element = Array.get(object, i);
                    answer.add(element);
                }
                return answer;
            }
        }
        if (type == String.class) {
            return object.toString();
        } else if (type == Character.class) {
            return box(castToChar(object));
        } else if (type == Boolean.class) {
            return box(castToBoolean(object));
        } else if (type == Class.class) {
            return castToClass(object);
        } else if (Number.class.isAssignableFrom(type)) {
            Number n = castToNumber(object);
            if (type == Byte.class) {
                return new Byte(n.byteValue());
            } else if (type == Character.class) {
                return new Character((char) n.intValue());
            } else if (type == Short.class) {
                return new Short(n.shortValue());
            } else if (type == Integer.class) {
                return new Integer(n.intValue());
            } else if (type == Long.class) {
                return new Long(n.longValue());
            } else if (type == Float.class) {
                return new Float(n.floatValue());
            } else if (type == Double.class) {
                Double answer = new Double(n.doubleValue());
                //throw a runtime exception if conversion would be out-of-range for the type.
                if (!(n instanceof Double) && (answer.doubleValue() == Double.NEGATIVE_INFINITY
                        || answer.doubleValue() == Double.POSITIVE_INFINITY)) {
                    throw new GroovyRuntimeException("Automatic coercion of " + n.getClass().getName()
                            + " value " + n + " to double failed.  Value is out of range.");
                }
                return answer;
            } else if (type == BigDecimal.class) {
                return new BigDecimal(n.toString());
            } else if (type == BigInteger.class) {
                if (object instanceof Float || object instanceof Double) {
                    BigDecimal bd = new BigDecimal(n.doubleValue());
                    return bd.toBigInteger();
                } else if (object instanceof BigDecimal) {
                    return ((BigDecimal) object).toBigInteger();
                } else {
                    return new BigInteger(n.toString());
                }
            }
        } else if (type.isPrimitive()) {
            if (type == boolean.class) {
               return box(booleanUnbox(object)); 
            } else if (type == byte.class) {
                return box(byteUnbox(object));
            } else if (type == char.class) {
                return box(charUnbox(object));
            } else if (type == short.class) {
                return box(shortUnbox(object));
            } else if (type == int.class) {
                return box(intUnbox(object));
            } else if (type == long.class) {
                return box(longUnbox(object));
            } else if (type == float.class) {
                return box(floatUnbox(object));
            } else if (type == double.class) {
                Double answer = new Double(doubleUnbox(object));
                //throw a runtime exception if conversion would be out-of-range for the type.
                if (!(object instanceof Double) && (answer.doubleValue() == Double.NEGATIVE_INFINITY
                        || answer.doubleValue() == Double.POSITIVE_INFINITY)) {
                    throw new GroovyRuntimeException("Automatic coercion of " + object.getClass().getName()
                            + " value " + object + " to double failed.  Value is out of range.");
                }
                return answer;
            }
        }
        Object[] args = null;
        if (object instanceof Collection) {
            Collection list = (Collection) object;
            args = list.toArray();
        } else if (object instanceof Object[]) {
            args = (Object[]) object;
        } else if (object instanceof Map) {
            // emulate named params constructor
            args = new Object[1];
            args[0] = object;
        }
        if (args != null) {
            // lets try invoke the constructor with the list as arguments
            // such as for creating a Dimension, Point, Color etc.
            try {
                return InvokerHelper.invokeConstructorOf(type, args);
            } catch (InvokerInvocationException iie){
                throw iie;
            } catch (Exception e) {
                // lets ignore exception and return the original object
                // as the caller has more context to be able to throw a more
                // meaningful exception
            }
        }
        throw new GroovyCastException(object,type);
    }

    private static Class castToClass(Object object) {
        try {
            return Class.forName (object.toString());
        } catch (Exception e) {
            throw new GroovyCastException(object,Class.class);
        }
    }

    public static Object asArray(Object object, Class type) {
        Collection list = asCollection(object);
        int size = list.size();
        Class elementType = type.getComponentType();
        Object array = Array.newInstance(elementType, size);
        int idx = 0;

        if (boolean.class.equals(elementType)) {
            for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                Object element = iter.next();
                Array.setBoolean(array, idx, booleanUnbox(element));
            }
        }
        else if (byte.class.equals(elementType)) {
            for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                Object element = iter.next();
                Array.setByte(array, idx, byteUnbox(element));
            }
        }
        else if (char.class.equals(elementType)) {
            for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                Object element = iter.next();
                Array.setChar(array, idx, charUnbox(element));
            }
        }
        else if (double.class.equals(elementType)) {
            for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                Object element = iter.next();
                Array.setDouble(array, idx, doubleUnbox(element));
            }
        }
        else if (float.class.equals(elementType)) {
            for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                Object element = iter.next();
                Array.setFloat(array, idx, floatUnbox(element));
            }
        }
        else if (int.class.equals(elementType)) {
            for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                Object element = iter.next();
                Array.setInt(array, idx, intUnbox(element));
            }
        }
        else if (long.class.equals(elementType)) {
            for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                Object element = iter.next();
                Array.setLong(array, idx, longUnbox(element));
            }
        }
        else if (short.class.equals(elementType)) {
            for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                Object element = iter.next();
                Array.setShort(array, idx, shortUnbox(element));
            }
        }
        else {
            for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                Object element = iter.next();
                Object coercedElement = castToType(element, elementType);
                Array.set(array, idx, coercedElement);
            }
        }
        return array;
    }
    
    public static Collection asCollection(Object value) {
        if (value == null) {
            return Collections.EMPTY_LIST;
        }
        else if (value instanceof Collection) {
            return (Collection) value;
        }
        else if (value instanceof Map) {
            Map map = (Map) value;
            return map.entrySet();
        }
        else if (value.getClass().isArray()) {
            if (value.getClass().getComponentType().isPrimitive()) {
                return primitiveArrayToList(value);
            }
            return Arrays.asList((Object[]) value);
        }
        else if (value instanceof MethodClosure) {
            MethodClosure method = (MethodClosure) value;
            IteratorClosureAdapter adapter = new IteratorClosureAdapter(method.getDelegate());
            method.call(adapter);
            return adapter.asList();
        }
        else if (value instanceof String) {
            return DefaultGroovyMethods.toList((String) value);
        }
        else if (value instanceof GString) {
            return DefaultGroovyMethods.toList(value.toString());
        }
        else if (value instanceof File) {
            try {
                return DefaultGroovyMethods.readLines((File) value);
            }
            catch (IOException e) {
                throw new GroovyRuntimeException("Error reading file: " + value, e);
            }
        }
        else {
            // lets assume its a collection of 1
            return Collections.singletonList(value);
        }
    }
    
    /**
     * Allows conversion of arrays into a mutable List
     *
     * @return the array as a List
     */
    public static List primitiveArrayToList(Object array) {
        int size = Array.getLength(array);
        List list = new ArrayList(size);
        for (int i = 0; i < size; i++) {
            Object item = Array.get(array, i);
            if (item != null && item.getClass().isArray() && item.getClass().getComponentType().isPrimitive()) {
                item = primitiveArrayToList(item);
            }
            list.add(item);
        }
        return list;
    }
    
    public static Object[] primitiveArrayBox(Object array) {
        int size = Array.getLength(array);
        Object[] ret = (Object[]) Array.newInstance(ReflectionCache.autoboxType(array.getClass().getComponentType()), size);
        for (int i = 0; i < size; i++) {
            ret[i]=Array.get(array, i);
        }
        return ret;
    }
    
    /**
     * Compares the two objects handling nulls gracefully and performing numeric type coercion if required
     */
    public static int compareTo(Object left, Object right) {
        if (left == right) {
            return 0;
        }
        if (left == null) {
            return -1;
        }
        else if (right == null) {
            return 1;
        }
        if (left instanceof Comparable) {
            if (left instanceof Number) {
                if (isValidCharacterString(right)) {
                    return castToChar(left) - castToChar(right);
                } else if (right instanceof Character || right instanceof Number) {
                    return DefaultGroovyMethods.compareTo((Number) left, castToNumber(right));
                }
            }
            else if (left instanceof Character) {
                if (isValidCharacterString(right)) {
                    return castToChar(left) - castToChar(right);
                }
                else if (right instanceof Number) {
                    return castToChar(left) - castToChar(right);
                }
            }
            else if (right instanceof Number) {
                if (isValidCharacterString(left)) {
                    return castToChar(left) - castToChar(right);
                } 
            }
            else if (left instanceof String && right instanceof Character) {
                return ((String) left).compareTo(right.toString());
            }
            else if (left instanceof String && right instanceof GString) {
                return ((String) left).compareTo(right.toString());
            }
            Comparable comparable = (Comparable) left;
            return comparable.compareTo(right);
        }

        throw new GroovyRuntimeException("Cannot compare " + left.getClass().getName() + " with value '" +
                left + "' and " + right.getClass().getName() + " with value '" + right + "'");
    }
    
    public static boolean compareEqual(Object left, Object right) {
        if (left == right) return true;
        if (left == null || right == null) return false;
        if (left instanceof Comparable) {
            return compareTo(left, right) == 0;
        }
        // handle arrays on both sides as special case for efficiency
        Class leftClass = left.getClass();
        Class rightClass = right.getClass();
        if (leftClass.isArray() && rightClass.isArray()) {
            return compareArrayEqual(left, right);
        }
        if (leftClass.isArray() && leftClass.getComponentType().isPrimitive()) {
            left = primitiveArrayToList(left);
        }
        if (rightClass.isArray() && rightClass.getComponentType().isPrimitive()) {
            right = primitiveArrayToList(right);
        }
        if (left instanceof Object[] && right instanceof List) {
            return DefaultGroovyMethods.equals((Object[]) left, (List) right);
        }
        if (left instanceof List && right instanceof Object[]) {
            return DefaultGroovyMethods.equals((List) left, (Object[]) right);
        }
        if (left instanceof List && right instanceof List) {
            return DefaultGroovyMethods.equals((List) left, (List) right);
        }
        return ((Boolean) InvokerHelper.invokeMethod(left, "equals", right)).booleanValue();
    }

    public static boolean compareArrayEqual(Object left, Object right) {
        if (left == null) {
            return right == null;
        }
        if (right == null) {
            return false;
        }
        if (Array.getLength(left) != Array.getLength(right)) {
            return false;
        }
        for (int i = 0; i < Array.getLength(left); i++) {
            Object l = Array.get(left, i);
            Object r = Array.get(right, i);
            if (!compareEqual(l, r)) return false;
        }
        return true;
    }

    /**
     * @return true if the given value is a valid character string (i.e. has length of 1)
     */
    private static boolean isValidCharacterString(Object value) {
        if (value instanceof String) {
            String s = (String) value;
            if (s.length() == 1) {
                return true;
            }
        }
        return false;
    }

    public static int[] convertToIntArray(Object a) {
        int[] ans = null;

        // conservative coding
        if (a.getClass().getName().equals("[I")) {
            ans = (int[]) a;
        }
        else {
            Object[] ia = (Object[]) a;
            ans = new int[ia.length];
            for (int i = 0; i < ia.length; i++) {
                if (ia[i] == null) {
                    continue;
                }
                ans[i] = ((Number) ia[i]).intValue();
            }
        }
        return ans;
    }

    public static boolean[] convertToBooleanArray(Object a) {
        boolean[] ans = null;

        // conservative coding
        if (a.getClass().getName().equals("[Z")) {
            ans = (boolean[]) a;
        }
        else {
            Object[] ia = (Object[]) a;
            ans = new boolean[ia.length];
            for (int i = 0; i < ia.length; i++) {
                if (ia[i] == null) {
                    continue;
                }
                ans[i] = ((Boolean) ia[i]).booleanValue();
            }
        }
        return ans;
    }

    public static byte[] convertToByteArray(Object a) {
        byte[] ans = null;

        // conservative coding
        if (a.getClass().getName().equals("[B")) {
            ans = (byte[]) a;
        }
        else {
            Object[] ia = (Object[]) a;
            ans = new byte[ia.length];
            for (int i = 0; i < ia.length; i++) {
                if (ia[i] != null) {
                    ans[i] = ((Number) ia[i]).byteValue();
                }
            }
        }
        return ans;
    }

    public static short[] convertToShortArray(Object a) {
        short[] ans = null;

        // conservative coding
        if (a.getClass().getName().equals("[S")) {
            ans = (short[]) a;
        }
        else {
            Object[] ia = (Object[]) a;
            ans = new short[ia.length];
            for (int i = 0; i < ia.length; i++) {
                ans[i] = ((Number) ia[i]).shortValue();
            }
        }
        return ans;
    }

    public static char[] convertToCharArray(Object a) {
        char[] ans = null;

        // conservative coding
        if (a.getClass().getName().equals("[C")) {
            ans = (char[]) a;
        }
        else {
            Object[] ia = (Object[]) a;
            ans = new char[ia.length];
            for (int i = 0; i < ia.length; i++) {
                if (ia[i] == null) {
                    continue;
                }
                ans[i] = ((Character) ia[i]).charValue();
            }
        }
        return ans;
    }

    public static long[] convertToLongArray(Object a) {
        long[] ans = null;

        // conservative coding
        if (a.getClass().getName().equals("[J")) {
            ans = (long[]) a;
        }
        else {
            Object[] ia = (Object[]) a;
            ans = new long[ia.length];
            for (int i = 0; i < ia.length; i++) {
                if (ia[i] == null) {
                    continue;
                }
                ans[i] = ((Number) ia[i]).longValue();
            }
        }
        return ans;
    }

    public static float[] convertToFloatArray(Object a) {
        float[] ans = null;

        // conservative coding
        if (a.getClass().getName().equals("[F")) {
            ans = (float[]) a;
        }
        else {
            Object[] ia = (Object[]) a;
            ans = new float[ia.length];
            for (int i = 0; i < ia.length; i++) {
                if (ia[i] == null) {
                    continue;
                }
                ans[i] = ((Number) ia[i]).floatValue();
            }
        }
        return ans;
    }

    public static double[] convertToDoubleArray(Object a) {
        double[] ans = null;

        // conservative coding
        if (a.getClass().getName().equals("[D")) {
            ans = (double[]) a;
        }
        else {
            Object[] ia = (Object[]) a;
            ans = new double[ia.length];
            for (int i = 0; i < ia.length; i++) {
                if (ia[i] == null) {
                    continue;
                }
                ans[i] = ((Number) ia[i]).doubleValue();
            }
        }
        return ans;
    }

    public static Object convertToPrimitiveArray(Object a, Class type) {
        if (type == Byte.TYPE) {
            return convertToByteArray(a);
        }
        if (type == Boolean.TYPE) {
            return convertToBooleanArray(a);
        }
        if (type == Short.TYPE) {
            return convertToShortArray(a);
        }
        if (type == Character.TYPE) {
            return convertToCharArray(a);
        }
        if (type == Integer.TYPE) {
            return convertToIntArray(a);
        }
        if (type == Long.TYPE) {
            return convertToLongArray(a);
        }
        if (type == Float.TYPE) {
            return convertToFloatArray(a);
        }
        if (type == Double.TYPE) {
            return convertToDoubleArray(a);
        }
        else {
            return a;
        }
    }

}
