package org.eclipse.jst.jsf.validation.internal.el.operators;

import org.eclipse.core.resources.IFile;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jst.jsf.common.internal.types.LiteralType;
import org.eclipse.jst.jsf.common.internal.types.SignatureBasedType;
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.context.symbol.internal.provisional.IObjectSymbol;
import org.eclipse.jst.jsf.context.symbol.internal.provisional.ISymbol;
import org.eclipse.jst.jsf.context.symbol.internal.util.IObjectSymbolBasedValueType;
import org.eclipse.jst.jsf.designtime.internal.provisional.el.AbstractDTPropertyResolver;
import org.eclipse.jst.jsf.validation.internal.el.diagnostics.DiagnosticFactory;

/**
 * Handles the operator 'bracket' where bracket(expr-a, id-b) == 'expr-a[id-b]' in EL syntax
 * 
 * @author cbateman
 *
 */
public class BracketOperator extends MemberAccessorOperator
{
    private static final String OPERATOR_NAME_ARRAY_ACCESSOR = "array ('[]') accessor";

    /**
     * @param file 
     */
    public BracketOperator(final IFile file)
    {
        super(file);
    }

	protected SignatureBasedType handlePerformObjectSymbolValue(
			IObjectSymbolBasedValueType firstArg, ValueType secondArg)
	{
        // per JSP.2.3.4 step 5.2, if value-a is a list or array access
        if (firstArg.isInstanceOf(TypeConstants.TYPE_LIST)
                || Signature.getArrayCount(firstArg.getSignature()) > 0)
        {
            return handlePerformNumericPropertyAccessorBase(firstArg, secondArg);
        }

        // per JSP.2.3.4 step 5, if value-a is a map or if it is not 
        // a list or array (and therefore a bean), treat it as named property accessed object
        // if firstArg is a map then we must treat the access like a map.get(secondArg)

        // if we don't have a literal value with which to derive value-b, then
        // we can't get a property
        if (secondArg instanceof LiteralType)
        {
        	return handlePerformNamedPropertyAccessorBase(firstArg, (LiteralType)secondArg);
        }

        return null;
	}
	
	protected Diagnostic validateObjectSymbolValue(IObjectSymbolBasedValueType firstArg,
			ValueType secondArg) 
	{
        // per JSP.2.3.4 step 5.2, if value-a is a list or array access
        if (firstArg.isInstanceOf(TypeConstants.TYPE_LIST)
                || firstArg.getSymbol().getTypeDescriptor().isArray())
        {
            return validateNumericPropertyAccessorBase(firstArg, secondArg);
        }

        // per JSP.2.3.4 step 5, if value-a is a map or if it is not 
        // a list or array (and therefore a bean), treat it as named property accessed object
        // if firstArg is a map then we must treat the access like a map.get(secondArg)
		if (secondArg instanceof LiteralType)
		{
			return validateNamedPropertyAccessorBase(firstArg, (LiteralType) secondArg);
		}
        // otherwise, there's nothing we can guarantee
        return Diagnostic.OK_INSTANCE;
	}
	
	private Diagnostic validateNumericPropertyAccessorBase(IObjectSymbolBasedValueType firstArg, 
															ValueType secondArg)
	{
        try
        {
        	// secondArg must successfully coerce to integer
        	TypeCoercer.coerceToNumber(TypeTransformer.transformBoxPrimitives(secondArg.getSignature()));
        	
        	if (secondArg instanceof LiteralType)
        	{
                // this will throw a TypeCoercionExceptino if it won't
                // coerce
                Integer integerValue = 
                    (Integer) ((LiteralType)secondArg).coerceToNumber(Integer.class);

        		if (integerValue.intValue() < 0)
                {
        		    return DiagnosticFactory.create_POSSIBLE_ARRAY_INDEX_OUT_OF_BOUNDS(integerValue);
                }
        	}
            else
            {
                // if the argument is a non-literal string, we can't verify
                // that the coercion to integer won't throw an exception
                // at runtime
                if (TypeCoercer.typeIsString(secondArg.getSignature()))
                {
                    return DiagnosticFactory.create_UNARY_OP_STRING_CONVERSION_NOT_GUARANTEED(OPERATOR_NAME_ARRAY_ACCESSOR);
                }
            }
            
            // TODO: attempt to detect ArrayIndexOutOfBoundsException
            return Diagnostic.OK_INSTANCE;
        }
        catch (TypeCoercionException e)
        {
        	return DiagnosticFactory.create_BINARY_OP_COULD_NOT_MAKE_NUMERIC_COERCION(OPERATOR_NAME_ARRAY_ACCESSOR);
        }
	}
    
    private SignatureBasedType handlePerformNumericPropertyAccessorBase(IObjectSymbolBasedValueType firstArg, 
                                                            ValueType secondArg)
    {
        AbstractDTPropertyResolver propResolver = getPropertyResolver();
        int index = 0;
        if (secondArg instanceof LiteralType)
        {
            try {
                index = ((LiteralType)secondArg).coerceToNumber(Integer.class).intValue();
            } catch (TypeCoercionException e) {
                // suppress, just use index = 0
                // this maybe should be an assertion...
            }
        }
        
        final ISymbol symbol = 
            propResolver.getProperty(firstArg.getSymbol(), index);
        
        if (symbol instanceof IObjectSymbol)
        {
            return IObjectSymbolBasedValueType.getInstance(symbol);
        }
        
        // if can't be resolved, return null
        return null;
    }
}
