/*******************************************************************************
 * 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) {
    	if (TypeConstants.TYPE_JAVAOBJECT.equals(firstArg.getSignature()) ||
    			TypeConstants.TYPE_JAVAOBJECT.equals(secondArg.getSignature())) {
    		return Diagnostic.OK_INSTANCE;
    	}
    	
        // 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;
    }
     
}
