/*******************************************************************************
 * 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.BooleanLiteralType;
import org.eclipse.jst.jsf.common.internal.types.IAssignable;
import org.eclipse.jst.jsf.common.internal.types.TypeCoercer;
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.common.util.TypeUtil;
import org.eclipse.jst.jsf.validation.internal.el.diagnostics.DiagnosticFactory;

/**
 * Encapsulates the EL binary operators "<", ">", "<=", ">="
 * 
 * @author cbateman
 *
 */
/*package*/ abstract class LtGtRelationalBinaryOperator extends RelationalBinaryOperator 
{
    LtGtRelationalBinaryOperator(final DiagnosticFactory diagnosticFactory, String jsfVersion) 
    {
        super(diagnosticFactory, jsfVersion);
    }

    protected abstract boolean doRealOperation(Number firstArg, Number secondArg);

    protected abstract boolean doRealOperation(String firstArg, String secondArg); 

    public ValueType performOperation(ValueType firstArg, ValueType secondArg) 
    {
        // JSP.2.3.5.6 step 2 if either operand is null, then always false
        if (TypeCoercer.typeIsNull(firstArg.getSignature())
                || TypeCoercer.typeIsNull(secondArg.getSignature()))
        {
            return BooleanLiteralType.FALSE;
        }
        
        String boxedFirstType = TypeTransformer.transformBoxPrimitives(firstArg.getSignature());
        String boxedSecondType = TypeTransformer.transformBoxPrimitives(secondArg.getSignature());
        
        // JSP.2.3.5.6 step 3, if either is BigDecimal, promote both and compare
        if (TypeConstants.TYPE_BIG_DOUBLE.equals(boxedFirstType)
                || TypeConstants.TYPE_BIG_DOUBLE.equals(boxedSecondType))
        {
            return handleNumericComparison(firstArg, secondArg, BigDecimal.class);
        }
        
        // JSP.2.3.5.6, step 4 if either is a float or double, promote both to 
        // double and compare
        if (TypeConstants.TYPE_BOXED_DOUBLE.equals(boxedFirstType)
                || TypeConstants.TYPE_BOXED_FLOAT.equals(boxedFirstType)
                || TypeConstants.TYPE_BOXED_DOUBLE.equals(boxedSecondType)
                || TypeConstants.TYPE_BOXED_FLOAT.equals(boxedSecondType))
        {
            return handleNumericComparison(firstArg, secondArg, Double.class);
        }
        
        // JSP.2.3.5.6, step 5 if either is a big integer, promote and compare
        if (TypeConstants.TYPE_BIG_INTEGER.equals(boxedFirstType)
                || TypeConstants.TYPE_BIG_INTEGER.equals(boxedSecondType))
        {
            return handleNumericComparison(firstArg, secondArg, BigInteger.class);
        }
        
        // JSP.2.3.5.6, step 6 if either is Long or smaller, coerce both to Long
        if (TypeConstants.TYPE_BOXED_LONG.equals(boxedFirstType)
                || TypeConstants.TYPE_BOXED_LONG.equals(boxedSecondType)
                || TypeConstants.TYPE_BOXED_INTEGER.equals(boxedFirstType)
                || TypeConstants.TYPE_BOXED_INTEGER.equals(boxedSecondType)
                || TypeConstants.TYPE_BOXED_SHORT.equals(boxedFirstType)
                || TypeConstants.TYPE_BOXED_SHORT.equals(boxedSecondType)
                || TypeConstants.TYPE_BOXED_BYTE.equals(boxedFirstType)
                || TypeConstants.TYPE_BOXED_BYTE.equals(boxedSecondType)
                || TypeConstants.SIGNATURE_BOXED_CHARACTER.equals(boxedFirstType)
                || TypeConstants.SIGNATURE_BOXED_CHARACTER.equals(boxedSecondType))
        {
            return handleNumericComparison(firstArg, secondArg, Long.class);
        }
        
        // JSP.2.3.5.7, step 7 if either is a string, coerce to string and
        // compare lexically
        if (TypeConstants.TYPE_STRING.equals(boxedFirstType)
                || TypeConstants.TYPE_STRING.equals(boxedSecondType))
        {
            return handleStringComparison(firstArg, secondArg);
        }
        
        // JSP.2.3.5.7, steps 8 and 9 -- if either one implements the
        // Comparable interface, then as far as we can determine statically
        // (compareTo may not work on the other arg, but who knows),
        // we are good
        if (firstArg.isInstanceOf(TypeConstants.TYPE_COMPARABLE)
                || secondArg.isInstanceOf(TypeConstants.TYPE_COMPARABLE))
        {
            if (checkIfIncompatibleEnums(firstArg, secondArg))
            {
                // error: no point in validating further since expr will probably throw an exception
                return null;
            }
            
            return new ValueType(Signature.SIG_BOOLEAN, IAssignable.ASSIGNMENT_TYPE_RHS);
        }
        
        // JSP.2.3.5.6, step 10 -- otherwise, error
        return null;

    }

    public Diagnostic validate(ValueType firstArg, ValueType secondArg) 
    {
        // JSP.2.3.5.6 step 2 if either operand is null, then always false
        if (TypeCoercer.typeIsNull(firstArg.getSignature())
                || TypeCoercer.typeIsNull(secondArg.getSignature()))
        {
            return _diagnosticFactory.
                create_BINARY_OP_EQUALITY_COMP_WITH_NULL_ALWAYS_EVAL_SAME(Messages.getString("LtGtRelationalBinaryOperator.ConstantName.False")); //$NON-NLS-1$
        }
        
        String boxedFirstType = TypeTransformer.transformBoxPrimitives(firstArg.getSignature());
        String boxedSecondType = TypeTransformer.transformBoxPrimitives(secondArg.getSignature());
        
        // JSP.2.3.5.6 step 3, if either is BigDecimal, promote both and compare
        if (TypeConstants.TYPE_BIG_DOUBLE.equals(boxedFirstType)
                || TypeConstants.TYPE_BIG_DOUBLE.equals(boxedSecondType))
        {
            return validateNumericComparison(firstArg, secondArg, BigDecimal.class);
        }
        
        // JSP.2.3.5.6, step 4 if either is a float or double, promote both to 
        // double and compare
        if (TypeConstants.TYPE_BOXED_DOUBLE.equals(boxedFirstType)
                || TypeConstants.TYPE_BOXED_FLOAT.equals(boxedFirstType)
                || TypeConstants.TYPE_BOXED_DOUBLE.equals(boxedSecondType)
                || TypeConstants.TYPE_BOXED_FLOAT.equals(boxedSecondType))
        {
            return validateNumericComparison(firstArg, secondArg, Double.class);
        }
        
        // JSP.2.3.5.6, step 5 if either is a big integer, promote and compare
        if (TypeConstants.TYPE_BIG_INTEGER.equals(boxedFirstType)
                || TypeConstants.TYPE_BIG_INTEGER.equals(boxedSecondType))
        {
            return validateNumericComparison(firstArg, secondArg, BigInteger.class);
        }
        
        // JSP.2.3.5.6, step 6 if either is Long or smaller, coerce both to Long
        if (TypeConstants.TYPE_BOXED_LONG.equals(boxedFirstType)
                || TypeConstants.TYPE_BOXED_LONG.equals(boxedSecondType)
                || TypeConstants.TYPE_BOXED_INTEGER.equals(boxedFirstType)
                || TypeConstants.TYPE_BOXED_INTEGER.equals(boxedSecondType)
                || TypeConstants.TYPE_BOXED_SHORT.equals(boxedFirstType)
                || TypeConstants.TYPE_BOXED_SHORT.equals(boxedSecondType)
                || TypeConstants.TYPE_BOXED_BYTE.equals(boxedFirstType)
                || TypeConstants.TYPE_BOXED_BYTE.equals(boxedSecondType)
                || TypeConstants.SIGNATURE_BOXED_CHARACTER.equals(boxedFirstType)
                || TypeConstants.SIGNATURE_BOXED_CHARACTER.equals(boxedSecondType))
        {
            return validateNumericComparison(firstArg, secondArg, Long.class);
        }
        
        // JSP.2.3.5.7, step 7 if either is a string, coerce to string and
        // compare lexically
        if (TypeConstants.TYPE_STRING.equals(boxedFirstType)
                || TypeConstants.TYPE_STRING.equals(boxedSecondType))
        {
            return validateStringComparison(firstArg, secondArg);
        }
        
        // JSP.2.3.5.7, steps 8 and 9 -- if either one implements the
        // Comparable interface, then as far as we can determine statically
        // (compareTo may not work on the other arg, but who knows),
        // we are good
        if (firstArg.isInstanceOf(TypeConstants.TYPE_COMPARABLE)
                || secondArg.isInstanceOf(TypeConstants.TYPE_COMPARABLE))
        {
            Diagnostic diag = Diagnostic.OK_INSTANCE;
            if(checkIfIncompatibleEnums(firstArg, secondArg))
            {
                diag = _diagnosticFactory.create_BINARY_OP_COMPARISON_OF_ENUMS_INCOMPATIBLE();
            }
            return diag;
        }
        
        // JSP.2.3.5.6, step 10 -- otherwise, error
        return _diagnosticFactory.create_BINARY_OP_NO_AVAILABLE_TYPE_COERCION();
    }

    /**
     * @param firstArg
     * @param secondArg
     * @return diagnostic if firstArg and secondArg are incompatible with each other
     * for compareTo purpose or OK if not
     */
    private boolean checkIfIncompatibleEnums(ValueType firstArg,
            ValueType secondArg) 
    {
        if (firstArg.isEnumType()
                && secondArg.isEnumType()
                && !TypeUtil.isEnumsCompareCompatible(firstArg.getSignature()
                                                    , secondArg.getSignature()))
        {
            return true;
        }
        
        return false;
    }

}
