/*******************************************************************************
 * 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 the EL modulo operator: % or mod
 * Based JSP.2.3.5.3
 * 
 * @author cbateman
 *
 */
/*package*/ class ModArithmeticBinaryOperator extends ArithmeticBinaryOperator 
{
    private static final String MODULO = "modulo";

    ModArithmeticBinaryOperator(DiagnosticFactory diagnosticFactory) {
        super(diagnosticFactory);
    }

    public ValueType performOperation(ValueType firstArg, ValueType secondArg) 
    {
        // JSP.2.3.5.3, step 1 if both null, then return zero
        if (TypeCoercer.typeIsNull(firstArg.getSignature())
                && TypeCoercer.typeIsNull(secondArg.getSignature()))
        {
            return IntegerLiteralType.ZERO;
        }

        final String boxedFirstArg = TypeTransformer.transformBoxPrimitives(firstArg.getSignature());
        final String boxedSecondArg = TypeTransformer.transformBoxPrimitives(secondArg.getSignature());
        
        // JSP.2.3.5.3, step 2, if either arg is BigDecimal, Float, Double
        // or String (ignoring whether it is value coercable), then coerce
        // to Double and do op
        if (TypeConstants.TYPE_BIG_DOUBLE.equals(boxedFirstArg)
                || TypeConstants.TYPE_BIG_DOUBLE.equals(boxedSecondArg)
                || TypeConstants.TYPE_BOXED_DOUBLE.equals(boxedFirstArg)
                || TypeConstants.TYPE_BOXED_DOUBLE.equals(boxedSecondArg)
                || TypeConstants.TYPE_BOXED_FLOAT.equals(boxedFirstArg)
                || TypeConstants.TYPE_BOXED_FLOAT.equals(boxedSecondArg))
        {
            // TODO: handle case where one is a literal or resolvable string value
            // that containss ".", "e" or "E"
            return performDouble(firstArg, secondArg);
        }
        
        // JSP.2.3.5.3, step 3, if either arg is a BigInteger, coerce
        // both to BigInteger
        if (TypeConstants.TYPE_BIG_INTEGER.equals(boxedFirstArg)
                || TypeConstants.TYPE_BIG_INTEGER.equals(boxedSecondArg))
        {
            return performBigInteger(firstArg, secondArg);
        }
        
        // JSP.2.3.5.3, step 4, otherwise try to perform as a Long op
        return performLong(firstArg, secondArg);
    }

    public Diagnostic validate(ValueType firstArg, ValueType secondArg) {
        // JSP.2.3.5.3, step 1 if both null, then return zero
        if (TypeCoercer.typeIsNull(firstArg.getSignature())
                && TypeCoercer.typeIsNull(secondArg.getSignature()))
        {
            return _diagnosticFactory.create_BINARY_OP_BOTH_OPERANDS_NULL(MODULO);
        }

        final String boxedFirstArg = TypeTransformer.transformBoxPrimitives(firstArg.getSignature());
        final String boxedSecondArg = TypeTransformer.transformBoxPrimitives(secondArg.getSignature());
        
        // JSP.2.3.5.3, step 2, if either arg is BigDecimal, Float, Double
        // or String (ignoring whether it is value coercable), then coerce
        // to Double and do op
        if (TypeConstants.TYPE_BIG_DOUBLE.equals(boxedFirstArg)
                || TypeConstants.TYPE_BIG_DOUBLE.equals(boxedSecondArg)
                || TypeConstants.TYPE_BOXED_DOUBLE.equals(boxedFirstArg)
                || TypeConstants.TYPE_BOXED_DOUBLE.equals(boxedSecondArg)
                || TypeConstants.TYPE_BOXED_FLOAT.equals(boxedFirstArg)
                || TypeConstants.TYPE_BOXED_FLOAT.equals(boxedSecondArg))
        {
            // TODO: handle case where one is a literal or resolvable string value
            // that containss ".", "e" or "E"
            return validateDouble(firstArg, secondArg);
        }
        
        // JSP.2.3.5.3, step 3, if either arg is a BigInteger, coerce
        // both to BigInteger
        if (TypeConstants.TYPE_BIG_INTEGER.equals(boxedFirstArg)
                || TypeConstants.TYPE_BIG_INTEGER.equals(boxedSecondArg))
        {
            return validateBigInteger(firstArg, secondArg);
        }
        
        // JSP.2.3.5.3, step 4, otherwise try to perform as a Long op
        return validateLong(firstArg, secondArg);
    }

    private ValueType performDouble(ValueType firstArg, ValueType secondArg)
    {
        try
        {
            TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(firstArg.getSignature()));
            TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(secondArg.getSignature()));
            
            Number secondValue = null;
            
            if (secondArg instanceof LiteralType)
            {
                secondValue = ((LiteralType)secondArg).coerceToNumber(Double.class);
                
                if (secondValue.doubleValue() == 0.0)
                {
                    // division by zero
                    return null;
                }
            }
            
            Number firstValue = null;
            
            if (firstArg instanceof LiteralType)
            {
                firstValue = ((LiteralType)firstArg).coerceToNumber(Double.class);
            }
            
            if (firstValue != null && secondValue != null)
            {
                return new FloatLiteralType(
                        doRealOperation(new Double(firstValue.doubleValue()), 
                                        new Double(secondValue.doubleValue())).doubleValue());
            }

            // if we get to here, the coercion is valid, so a Double will be
            // returned
            return new ValueType(Signature.SIG_DOUBLE, IAssignable.ASSIGNMENT_TYPE_RHS);
        }
        catch (TypeCoercionException tce)
        {
            // could not coerce, so null
            return null;
        }
    }
    
    private ValueType performBigInteger(ValueType firstArg, ValueType secondArg)
    {
        try
        {
            TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(firstArg.getSignature()));
            TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(secondArg.getSignature()));
            
            // check second arg for zero
            if (secondArg instanceof LiteralType)
            {
                if (((LiteralType)secondArg).coerceToNumber(BigInteger.class).equals(BigInteger.ZERO))
                {
                    // division by zero
                    return null;
                }
            }
            
            // since one of the args is BigInteger, they are not both literals,
            // so if we get to here, we have a successful mod of two
            // big integers to one big integer
            return new ValueType(TypeConstants.TYPE_BIG_INTEGER, IAssignable.ASSIGNMENT_TYPE_RHS);
        }
        catch (TypeCoercionException tce)
        {
            // no coercion
            return null;
        }
    }
    
    private ValueType performLong(ValueType firstArg, ValueType secondArg)
    {
        try
        {
            TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(firstArg.getSignature()));
            TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(secondArg.getSignature()));
        
            Number secondValue = null;
            
            if (secondArg instanceof LiteralType)
            {
                secondValue = ((LiteralType)secondArg).coerceToNumber(Long.class);
                
                if (secondValue.longValue() == 0)
                {
                    // division by zero
                    return null;
                }
            }
            
            Number firstValue = null;
            
            if (firstArg instanceof LiteralType)
            {
                firstValue = ((LiteralType)firstArg).coerceToNumber(Long.class);
            }
            
            if (firstValue != null && secondValue != null)
            {
                return new IntegerLiteralType(
                        doRealOperation(Long.valueOf(firstValue.longValue()), 
                                        Long.valueOf(secondValue.longValue())).longValue());
            }

            // if we get to here, the coercion is valid, so a Long will be
            // returned
            return new ValueType(Signature.SIG_LONG, IAssignable.ASSIGNMENT_TYPE_RHS);
        }
        catch (TypeCoercionException tce)
        {
            // could not coerce, so null
            return null;
        }
    }
    
    private Diagnostic validateDouble(ValueType firstArg, ValueType secondArg)
    {
        try
        {
            TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(firstArg.getSignature()));
            TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(secondArg.getSignature()));
            
            Number secondValue = null;
            
            if (secondArg instanceof LiteralType)
            {
                secondValue = ((LiteralType)secondArg).coerceToNumber(Double.class);
                
                if (secondValue.doubleValue() == 0.0)
                {
                    // division by zero
                    return _diagnosticFactory.create_BINARY_OP_POSSIBLE_DIVISION_BY_ZERO();
                }
            }
            
            Number firstValue = null;
            
            if (firstArg instanceof LiteralType)
            {
                firstValue = ((LiteralType)firstArg).coerceToNumber(Double.class);
            }
            
            if (firstValue != null && secondValue != null)
            {
                return _diagnosticFactory.
                    create_BINARY_OP_CONSTANT_EXPRESSION_ALWAYS_EVAL_SAME
                        (MODULO, Double.toString(
                                firstValue.doubleValue()%secondValue.doubleValue()));
            }

            // if we get to here, the coercion is valid, so a Double will be
            // returned and everything is good
            return Diagnostic.OK_INSTANCE;
        }
        catch (TypeCoercionException tce)
        {
            // could not coerce, so error
            return _diagnosticFactory.
                create_BINARY_OP_COULD_NOT_MAKE_NUMERIC_COERCION(MODULO);
        }
    }
    
    private Diagnostic validateBigInteger(ValueType firstArg, ValueType secondArg)
    {
        try
        {
            TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(firstArg.getSignature()));
            TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(secondArg.getSignature()));
            
            // check second arg for zero
            if (secondArg instanceof LiteralType)
            {
                if (((LiteralType)secondArg).coerceToNumber(BigInteger.class).equals(BigInteger.ZERO))
                {
                    // division by zero
                    return _diagnosticFactory.create_BINARY_OP_POSSIBLE_DIVISION_BY_ZERO();
                }
            }
            
            // since one of the args is BigInteger, they are not both literals,
            // so if we get to here, we have a successful mod of two
            // big integers to one big integer
            return Diagnostic.OK_INSTANCE;
        }
        catch (TypeCoercionException tce)
        {
            // no coercion
            return _diagnosticFactory.
                create_BINARY_OP_COULD_NOT_MAKE_NUMERIC_COERCION(MODULO);
        }        
    }
    
    private Diagnostic validateLong(ValueType firstArg, ValueType secondArg)
    {
        try
        {
            TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(firstArg.getSignature()));
            TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(secondArg.getSignature()));
        
            Number secondValue = null;
            
            if (secondArg instanceof LiteralType)
            {
                secondValue = ((LiteralType)secondArg).coerceToNumber(Long.class);
                
                if (secondValue.longValue() == 0)
                {
                    // division by zero
                    return _diagnosticFactory.
                        create_BINARY_OP_POSSIBLE_DIVISION_BY_ZERO();
                }
            }
            
            Number firstValue = null;
            
            if (firstArg instanceof LiteralType)
            {
                firstValue = ((LiteralType)firstArg).coerceToNumber(Long.class);
            }
            
            if (firstValue != null && secondValue != null)
            {
                return _diagnosticFactory.
                    create_BINARY_OP_CONSTANT_EXPRESSION_ALWAYS_EVAL_SAME
                        (MODULO, Long.toString(firstValue.longValue()%secondValue.longValue())); 
            }

            // if we get to here, the coercion is valid, so a Long will be
            // returned
            return Diagnostic.OK_INSTANCE;
        }
        catch (TypeCoercionException tce)
        {
            // could not coerce, so error
            return _diagnosticFactory.
                create_BINARY_OP_COULD_NOT_MAKE_NUMERIC_COERCION(MODULO);
        }
    }
    
    protected Long doRealOperation(Long firstArg, Long secondArg) {
        return Long.valueOf(firstArg.longValue() % secondArg.longValue());
     }

     protected Double doRealOperation(Double firstArg, Double secondArg) {
         return new Double(firstArg.doubleValue() % secondArg.doubleValue());
     }

     protected BigDecimal doRealOperation(BigDecimal firstArg,
             BigDecimal secondArg) {
        return new BigDecimal(firstArg.doubleValue() % secondArg.doubleValue());
     }

    protected String getOperatorName() {
        return MODULO;
    }
     
}
