/*******************************************************************************
 * 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 
{
    NoDivArithmeticBinaryOperator(DiagnosticFactory diagnosticFactory) {
        super(diagnosticFactory);
    }

    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());
        }
    }

}
