/*******************************************************************************
 * 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.validation.internal.el.operators;

import java.math.BigDecimal;
import java.math.BigInteger;

import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jst.jsf.common.internal.types.FloatLiteralType;
import org.eclipse.jst.jsf.common.internal.types.IAssignable;
import org.eclipse.jst.jsf.common.internal.types.IntegerLiteralType;
import org.eclipse.jst.jsf.common.internal.types.LiteralType;
import org.eclipse.jst.jsf.common.internal.types.TypeCoercer;
import org.eclipse.jst.jsf.common.internal.types.TypeCoercionException;
import org.eclipse.jst.jsf.common.internal.types.TypeConstants;
import org.eclipse.jst.jsf.common.internal.types.TypeTransformer;
import org.eclipse.jst.jsf.common.internal.types.ValueType;
import org.eclipse.jst.jsf.validation.internal.el.diagnostics.DiagnosticFactory;

/**
 * Represents non-dividing arithmetic EL operators: +,-,*
 * Based on JSP.2.3.5.1
 * 
 * @author cbateman
 *
 */
/*package*/ abstract class NoDivArithmeticBinaryOperator extends ArithmeticBinaryOperator 
{
    protected abstract Long doRealOperation(Long firstArg, Long secondArg);
    
    protected abstract Double doRealOperation(Double firstArg, Double secondArg);

    public ValueType performOperation(ValueType firstArg, ValueType secondArg)
    {
        // JSP.2.3.5.1, step 1, if either arg is null, return (Long) 0
        if (TypeCoercer.typeIsNull(firstArg.getSignature())
                && TypeCoercer.typeIsNull(secondArg.getSignature()))
        {
            return new IntegerLiteralType(0);
        }
        
        final String boxedFirstArg = TypeTransformer.transformBoxPrimitives(firstArg.getSignature());
        final String boxedSecondArg = TypeTransformer.transformBoxPrimitives(secondArg.getSignature());
        
        // JSP.2.3.5.1, step 2, if either arg is a BigDecimal, coerce to BigDecimal
        // and apply
        if (TypeConstants.TYPE_BIG_DOUBLE.equals(boxedFirstArg)
                || TypeConstants.TYPE_BIG_DOUBLE.equals(boxedSecondArg))
        {
            return handleNumericArithmetic(firstArg, secondArg, BigDecimal.class);
        }
        
        // JSP.2.3.5.1, step 3, if either arg is float or double or 
        // a String containing "., e or E", then coerce if the other is
        // a big int, coerce up to BigDecimal, else to Double
        // Note: we are ignoring strings we can't resolve to figure out
        // if the contain "., e or E".  Assume they always do
        if (TypeConstants.TYPE_BOXED_DOUBLE.equals(boxedFirstArg)
                ||TypeConstants.TYPE_BOXED_DOUBLE.equals(boxedSecondArg)
                ||TypeConstants.TYPE_BOXED_FLOAT.equals(boxedFirstArg)
                ||TypeConstants.TYPE_BOXED_FLOAT.equals(boxedSecondArg))
        {
            if (TypeConstants.TYPE_BIG_INTEGER.equals(boxedFirstArg)
                    ||TypeConstants.TYPE_BIG_INTEGER.equals(boxedSecondArg))
            {
                // if the other operand is BigInteger, treat as BigDecimal
                return handleNumericArithmetic(firstArg, secondArg, BigDecimal.class);
            }

            // otherwise as double
            return handleNumericArithmetic(firstArg, secondArg, Double.class);
        }
        
        // JSP.2.3.5.1, step 4, if one is a big integer, coerce to big integer
        if (TypeConstants.TYPE_BIG_INTEGER.equals(boxedFirstArg)
                || TypeConstants.TYPE_BIG_INTEGER.equals(boxedSecondArg))
        {
            return handleNumericArithmetic(firstArg, secondArg, BigInteger.class);
        }
        
        // JSP.2.3.5.1, step 5, otherwise, try to coerce to Long
        return handleNumericArithmetic(firstArg, secondArg, Long.class);
    }

    public Diagnostic validate(ValueType firstArg, ValueType secondArg) 
    {
        // JSP.2.3.5.1, step 1, if either arg is null, return (Long) 0
        if (TypeCoercer.typeIsNull(firstArg.getSignature())
                && TypeCoercer.typeIsNull(secondArg.getSignature()))
        {
            return DiagnosticFactory.create_BINARY_OP_BOTH_OPERANDS_NULL(getOperatorName());
        }
        
        final String boxedFirstArg = TypeTransformer.transformBoxPrimitives(firstArg.getSignature());
        final String boxedSecondArg = TypeTransformer.transformBoxPrimitives(secondArg.getSignature());
        
        // JSP.2.3.5.1, step 2, if either arg is a BigDecimal, coerce to BigDecimal
        // and apply
        if (TypeConstants.TYPE_BIG_DOUBLE.equals(boxedFirstArg)
                || TypeConstants.TYPE_BIG_DOUBLE.equals(boxedSecondArg))
        {
            return validateNumericArithmetic(firstArg, secondArg, BigDecimal.class);
        }
        
        // JSP.2.3.5.1, step 3, if either arg is float or double or 
        // a String containing "., e or E", then coerce if the other is
        // a big int, coerce up to BigDecimal, else to Double
        // Note: we are ignoring strings we can't resolve to figure out
        // if the contain "., e or E".  Assume they always do
        if (TypeConstants.TYPE_BOXED_DOUBLE.equals(boxedFirstArg)
                ||TypeConstants.TYPE_BOXED_DOUBLE.equals(boxedSecondArg)
                ||TypeConstants.TYPE_BOXED_FLOAT.equals(boxedFirstArg)
                ||TypeConstants.TYPE_BOXED_FLOAT.equals(boxedSecondArg))
        {
            if (TypeConstants.TYPE_BIG_INTEGER.equals(boxedFirstArg)
                    ||TypeConstants.TYPE_BIG_INTEGER.equals(boxedSecondArg))
            {
                // if the other operand is BigInteger, treat as BigDecimal
                return validateNumericArithmetic(firstArg, secondArg, BigDecimal.class);
            }

            // otherwise as double
            return validateNumericArithmetic(firstArg, secondArg, Double.class);
        }
        
        // JSP.2.3.5.1, step 4, if one is a big integer, coerce to big integer
        if (TypeConstants.TYPE_BIG_INTEGER.equals(boxedFirstArg)
                || TypeConstants.TYPE_BIG_INTEGER.equals(boxedSecondArg))
        {
            return validateNumericArithmetic(firstArg, secondArg, BigInteger.class);
        }
        
        // JSP.2.3.5.1, step 5, otherwise, try to coerce to Long
        return validateNumericArithmetic(firstArg, secondArg, Long.class);
    }

    /**
     * @param firstArg
     * @param secondArg
     * @param numberType
     * @return a value type based on the result of the arithmetic operation
     */
    protected ValueType handleNumericArithmetic(ValueType firstArg, ValueType secondArg, Class numberType)
    {
        try
        {
//            final String coercedFirstArg = 
                TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(firstArg.getSignature()));
//            final String coercedSecondArg = 
                TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(secondArg.getSignature()));
            
            if (firstArg instanceof LiteralType && secondArg instanceof LiteralType)
            {
                try
                {
                    Number firstValue = 
                        ((LiteralType)firstArg).coerceToNumber(numberType);
                    Number secondValue = 
                        ((LiteralType)secondArg).coerceToNumber(numberType);
                    
                    LiteralType result = null;
                    
                    if (numberType == Double.class)
                    {
                        Double resultValue = 
                            doRealOperation((Double)firstValue, 
                                    (Double) secondValue);
                        result = new FloatLiteralType(resultValue.doubleValue());
                    }
                    else if (numberType == Long.class)
                    {
                        Long resultValue = 
                            doRealOperation((Long) firstValue, (Long) secondValue);
                        result = new IntegerLiteralType(resultValue.longValue());
                    }
                    else
                    {
                        throw new AssertionError("unsupport arithmetic upcast type");
                    }
                    
                    return result;  
                }
                catch (TypeCoercionException tce)
                {
                    // could happen if two string literals passed
                    return null;
                }
            }
            
            // if we get to here, then we have two valid numeric arith
            // types, but at least one is not a literal, so the best we can
            // say is that the return will be the same asthe type of numeric
            // coercion
            if (numberType == BigDecimal.class)
            {
                return new ValueType(TypeConstants.TYPE_BIG_DOUBLE, IAssignable.ASSIGNMENT_TYPE_RHS);
            }
            else if (numberType == Double.class)
            {
                return new ValueType(Signature.SIG_DOUBLE, IAssignable.ASSIGNMENT_TYPE_RHS);
            }
            else if (numberType == BigInteger.class)
            {
                return new ValueType(TypeConstants.TYPE_BIG_INTEGER, IAssignable.ASSIGNMENT_TYPE_RHS);
            }
            else
            {
                return new ValueType(Signature.SIG_LONG, IAssignable.ASSIGNMENT_TYPE_RHS);
            }
        }
        catch (TypeCoercionException tce)
        {
            // coercion to number failed, so no go
            return null;
        }
    }
    
    /**
     * @param firstArg
     * @param secondArg
     * @param numberType
     * @return a diagnostic validating the arithmetic expr firstArg op secondArg
     */
    protected Diagnostic validateNumericArithmetic(ValueType firstArg, ValueType secondArg, Class numberType)
    {
        try
        {
//            final String coercedFirstArg = 
            TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(firstArg.getSignature()));
//            final String coercedSecondArg = 
            TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(secondArg.getSignature()));
            
            if (firstArg instanceof LiteralType && secondArg instanceof LiteralType)
            {
                try
                {
                    Number firstValue = 
                        ((LiteralType)firstArg).coerceToNumber(numberType);
                    Number secondValue = 
                        ((LiteralType)secondArg).coerceToNumber(numberType);
                    
                    Number result = null;
                    
                    if (numberType == Double.class)
                    {
                        result =
                            doRealOperation((Double)firstValue, 
                                    (Double) secondValue);
                    }
                    else if (numberType == Long.class)
                    {
                        result =
                            doRealOperation((Long) firstValue, (Long) secondValue);
                    }
                    else
                    {
                        throw new AssertionError("unsupport arithmetic upcast type");
                    }
                    
                    return DiagnosticFactory.
                        create_BINARY_OP_CONSTANT_EXPRESSION_ALWAYS_EVAL_SAME
                            (getOperatorName(), result.toString());  
                }
                catch (TypeCoercionException tce)
                {
                    // could happen when two strings are passed
                    return DiagnosticFactory.
                        create_BINARY_OP_COULD_NOT_COERCE_LITERALS_TO_NUMBERS();
                }
            }
            
            // if we get to here, then we have two valid numeric arith
            // types, but at least one is not a literal
            // everything should be ok
            return Diagnostic.OK_INSTANCE;
        }
        catch (TypeCoercionException tce)
        {
            // coercion to number failed, so no go
            return DiagnosticFactory.
                create_BINARY_OP_COULD_NOT_MAKE_NUMERIC_COERCION(getOperatorName());
        }
    }

}
