/*******************************************************************************
 * Copyright (c) 2001, 2007 Oracle Corporation and others.
 * 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:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/
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.jst.jsf.common.internal.types.LiteralType;
import org.eclipse.jst.jsf.common.internal.types.NullLiteralType;
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.TypeConstants;
import org.eclipse.jst.jsf.common.internal.types.ValueType;
import org.eclipse.jst.jsf.context.symbol.IMethodSymbol;
import org.eclipse.jst.jsf.context.symbol.IObjectSymbol;
import org.eclipse.jst.jsf.context.symbol.IPropertySymbol;
import org.eclipse.jst.jsf.context.symbol.ISymbol;
import org.eclipse.jst.jsf.context.symbol.internal.util.IMethodSymbolBasedType;
import org.eclipse.jst.jsf.context.symbol.internal.util.IObjectSymbolBasedValueType;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.designtime.DesignTimeApplicationManager;
import org.eclipse.jst.jsf.designtime.el.AbstractDTMethodResolver;
import org.eclipse.jst.jsf.designtime.el.AbstractDTPropertyResolver;
import org.eclipse.jst.jsf.validation.internal.el.diagnostics.DiagnosticFactory;

/**
 * Super-class for all operators whose function is to access members of an
 * EL object. i.e. the "." and "[]" operators
 * 
 * @author cbateman
 *
 */
public abstract class MemberAccessorOperator 
{
    /**
     * The source file for the EL expression in which this operator
     * is being evaluated.
     */
    protected final IFile                   _file;

    /**
     * the common factory used to create diagnostics
     */
    protected final DiagnosticFactory       _diagnosticFactory;
    
    // TODO: need to reconcile with BinaryOperator? performOperation must return
    // SignatureBasedType since it may return a method.  This can't happen
    // with other operators (besides eqiv [])
    /**
     * @param file 
     * @param diagnosticFactory 
     */
    protected MemberAccessorOperator(final IFile file, final DiagnosticFactory diagnosticFactory)
    {
        _file = file;
        _diagnosticFactory = diagnosticFactory;
    }

    /**
     * @param firstArg
     * @param secondArg
     * @return the result of validating the dot operation with these arguments.
     */
    public Diagnostic validate(ValueType firstArg, ValueType secondArg) 
    {
        if (!(firstArg instanceof IObjectSymbolBasedValueType))
        {
            throw new AssertionError("The first argument of the member operator must always be a symbol resolvable value type");
        }
        
        if (TypeCoercer.typeIsNull(secondArg.getSignature()))
        {
            return _diagnosticFactory.create_BINARY_OP_DOT_WITH_VALUEB_NULL(getOperatorName());
        }

        return validateObjectSymbolValue((IObjectSymbolBasedValueType) firstArg, secondArg);
    }
    
    /**
     * @param firstArg
     * @param secondArg
     * @return the diagnostic for member(firstArg, secondArg)
     */
    protected abstract Diagnostic validateObjectSymbolValue(IObjectSymbolBasedValueType firstArg, ValueType secondArg);
    
    /**
     * @param firstArg
     * @param secondArg
     * @return a validation of a named property accessible base (map or bean) given
     * an a literal key argument
     */
    protected Diagnostic validateNamedPropertyAccessorBase(IObjectSymbolBasedValueType firstArg
                                                  , LiteralType secondArg)
    {
		final IObjectSymbol curBaseSymbol = firstArg.getSymbol();
		
		final ISymbol nextSymbol = getMemberSymbol(firstArg.getSymbol(), 
											secondArg.getLiteralValueRaw());
		
		// if the x in x.y is an unconstrained map an it returns
		// a java.lang.Object, then return null.  We can't really say
		// anything meaningful about such a property anyway.
		// TODO: do we need to refine the type descriptor on such 
		// a property object to make this more precise?
		if (curBaseSymbol.supportsCoercion(TypeConstants.TYPE_MAP)
				&& nextSymbol instanceof IPropertySymbol
				&& TypeConstants.TYPE_JAVAOBJECT.equals(((IPropertySymbol)nextSymbol).getTypeDescriptor().getTypeSignature()))
		{
			// if we get a symbol back that's a generic object coming from a map
			// then stop validating; we can't tell anything for sure
			return Diagnostic.OK_INSTANCE;
		}
		
		if (nextSymbol == null)
		{
			return _diagnosticFactory.create_MEMBER_NOT_FOUND(secondArg.getLiteralValue()
			,firstArg.getSymbol().getName());
		}
		
		return Diagnostic.OK_INSTANCE;
    }
    
    /**
     * @param firstArg
     * @param secondArg
     * @return the resolved type for the operation or null if not computable
     */
    public SignatureBasedType performOperation(ValueType firstArg, ValueType secondArg) 
    {
        if (!(firstArg instanceof IObjectSymbolBasedValueType))
        {
        	return null;
        }

        // per JSP.2.3.4, if value-b is null, then return null (not literal null)
        if (TypeCoercer.typeIsNull(secondArg.getSignature()))
        {
            return null;
        }

        return handlePerformObjectSymbolValue((IObjectSymbolBasedValueType)firstArg, secondArg);
    }

    /**
     * @param firstArg -- represents value-a (expr-a after step 1) in JSP.2.3.4
     * @param secondArg -- represents value-b (expr-b after step 3) in JSP.2.3.4
     * @return the new ValueType for this operation or null
     */
    protected abstract SignatureBasedType handlePerformObjectSymbolValue(IObjectSymbolBasedValueType firstArg
                                                  , ValueType secondArg);

    /**
     * @param firstArg
     * @param secondArg
     * @return the resolved type for firstArg[secondArg] treating firstArg as a type
     * that uses a named property accessor (i.e. a map or bean but not a list or array)
     * or null if unresolved
     */
    protected SignatureBasedType handlePerformNamedPropertyAccessorBase(IObjectSymbolBasedValueType firstArg
                                                  , LiteralType secondArg)
    {
        final ISymbol symbol = 
            getMemberSymbol(firstArg.getSymbol(), secondArg.getLiteralValueRaw());

        if (symbol instanceof IPropertySymbol)
        {
            return new IObjectSymbolBasedValueType((IPropertySymbol)symbol);
        }
        else if (symbol instanceof IMethodSymbol)
        {
            return new IMethodSymbolBasedType((IMethodSymbol) symbol);
        }
        
        // fall-through and return null
        // per JSP2.3.4 steps 5 and 6, return null literal if map, null (error) otherwise
        if (firstArg.isInstanceOf(TypeConstants.TYPE_MAP))
        {
        	return NullLiteralType.SINGLETON;
        }
        return null;
    }
    
    /**
     * @param symbol
     * @param name
     * @return the member symbol of 'symbol' corresponding to 'name' or
     * null if there is no such member
     */
    protected final ISymbol getMemberSymbol(final IObjectSymbol symbol, final Object name)
    {
        ISymbol  memberSymbol = getPropertySymbol(symbol, name);

        if (memberSymbol != null)
        {
            return memberSymbol;
        }

        memberSymbol = getMethodSymbol(symbol, name);
        
        // otherwise, see if it's a valid method
        if (memberSymbol != null)
        {
            return memberSymbol;
        }
        
        // if not a property or method, then not a valid member
        return null;
    }
    
    /**
     * @param symbol
     * @param name
     * @return the property symbol called name relative to 'symbol' or null
     * if one doesn't exist
     */
    protected final ISymbol getPropertySymbol(final ISymbol symbol, final Object name)
    {
        AbstractDTPropertyResolver resolver = getPropertyResolver();
        
        if (resolver != null)
        {
            return resolver.getProperty(symbol,name);
        }
        
        JSFCorePlugin.log("Error acquiring property resolver", new Throwable());
        return null;
    }

    /**
     * @param symbol
     * @param name
     * @return the method symbol on 'symbol' corresponding to
     * 'name' or null if no such member
     */
    protected final IMethodSymbol getMethodSymbol(final IObjectSymbol symbol, final Object name)
    {
        AbstractDTMethodResolver resolver = getMethodResolver();
        
        if (resolver != null)
        {
            return resolver.getMethod(symbol, name);
        }
        
        JSFCorePlugin.log("Error acquiring property resolver", new Throwable());
        return null;

    }
    
    /**
     * @return the property resolver for the current source file
     */
    protected final AbstractDTPropertyResolver  getPropertyResolver()
    {
        return
            DesignTimeApplicationManager.getInstance(_file.getProject())
                .getPropertyResolver();
    }
    
    /**
     * @return the method resolver for the current source file
     */
    protected final AbstractDTMethodResolver getMethodResolver()
    {
        return
            DesignTimeApplicationManager.getInstance(_file.getProject())
                .getMethodResolver();
    }
    
    /**
     * @return a user-readable name of the operator (i.e. dot or bracket)
     */
    protected abstract String getOperatorName();
}
