/*******************************************************************************
 * Copyright (c) 2007 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.designtime.symbols;

import java.util.Arrays;
import java.util.HashMap;

import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jst.jsf.common.internal.types.TypeConstants;
import org.eclipse.jst.jsf.common.internal.types.ValueType;
import org.eclipse.jst.jsf.common.util.TypeUtil;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.symbol.ERuntimeSource;
import org.eclipse.jst.jsf.context.symbol.IComponentSymbol;
import org.eclipse.jst.jsf.context.symbol.IJavaTypeDescriptor2;
import org.eclipse.jst.jsf.context.symbol.IMapTypeDescriptor;
import org.eclipse.jst.jsf.context.symbol.ISymbol;
import org.eclipse.jst.jsf.context.symbol.SymbolFactory;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.tld.IJSFConstants;
import org.eclipse.jst.jsf.validation.internal.ValidationPreferences;
import org.eclipse.jst.jsf.validation.internal.appconfig.AppConfigValidationUtil;
import org.eclipse.jst.jsf.validation.internal.el.ELExpressionValidator;
import org.eclipse.jst.jsf.validation.internal.el.IExpressionSemanticValidator;
import org.w3c.dom.Element;

/**
 * A framework provided variable factory for EL model objects that are
 * constructed based on DataModel's dervied from an EL expression. 
 * 
 * @author cbateman
 *
 */
public abstract class AbstractDataModelVariableFactory 
{
    /**
     * @param elText The EL expression text. Must not be null
     * @param elContext The document context pointing to elText in the source document. Must not be null
     * @param file The workspace resource that contains elText. Must not be null.
     * @return the value expression resolved from elText or null if it cannot
     * be resolved or elText doesn't resolve to value expression (i.e. is a method expression)
     */
    public final ValueType createValueExpression(final String elText, final IStructuredDocumentContext elContext, final IFile file)
    {
        assert elText != null;
        assert elContext != null;
        assert file != null;

        final ValidationPreferences prefs = 
            new ValidationPreferences(JSFCorePlugin.getDefault().getPreferenceStore());
        prefs.load();

        final ELExpressionValidator validator = 
            new ELExpressionValidator(elContext, elText, file, prefs.getElPrefs());
        validator.validateXMLNode();
        final IExpressionSemanticValidator semValidator = 
            validator.getSemanticValidator();
        if (semValidator != null
                && semValidator.getExpressionType() instanceof ValueType)
        {
            return (ValueType) semValidator.getExpressionType();
        }
        return null;
    }
    
    /**
     * @param symbolName The name of the symbol to be created. Must not be null
     * @param signature The type signature of the array type. Must not be null
     * @param javaProject must not be null
     * @return a symbol based approximating an implicit DataModel wrapper for an array
     */
    protected final ISymbol createArraySymbol(final String symbolName, final String signature, final IJavaProject javaProject)
    {
        assert symbolName != null;
        assert signature != null;
        assert javaProject != null;
        
        final String arrayElementType = Signature.getElementType(signature);
        final int arrayCount = Signature.getArrayCount(signature);
        String  adjustedSignature = null;
        
        // if it is a single array nesting, then it will just be the element type,
        // but if it is a multi-dim array, then the scalar element will be an array
        // with one less nesting level.  It's a strange corner case to have an implicit
        // array of something as a row type, but it is a valid case.  I suppose
        // it may be happen if you want to have tables of tables in which the nested tables
        // in turn use nested variables as their type...
        if (arrayCount > 0)
        {
            adjustedSignature = Signature.createArraySignature(arrayElementType, arrayCount-1);
        }
        else
        {
            adjustedSignature = arrayElementType;
        }
        
        return createScalarSymbol(symbolName, adjustedSignature, javaProject);
    }

    /**
     * Implements default rules for taking an non-array value expression
     * and resolving it to a ISymbol modelling a JSF DataModel
     * 
     * @param symbolName
     * @param valueType
     * @param javaProject
     * @return a symbol where valueType is considered to be the base type upon
     * which a data model would be created.  This combines the possibility that the
     * value expression is either an explicit DataModel implementation or a
     * non-DataModel type for which JSF be default provides an implicit wrapper model.
     * 
     * List is treated as a special case here, since their are two subcases:
     *    1) the list is a raw type, in which case it must be treated as implicit and opaque (as to the type of the variable created)
     *    2) the list has Java 5 type argument information that can be used to infer the type of the row variable
     */
    public ISymbol createFromType(String symbolName, ValueType valueType,
            IJavaProject javaProject)
    {
        return internalCreateFromBaseType(symbolName, valueType, javaProject);
    }
    
    private ISymbol internalCreateFromBaseType(String symbolName, ValueType valueType,
            IJavaProject javaProject) 
    {
        // based on JSF 1.1 spec section 4.2.1.4 the data model
        // value binding can be one of a number of object that will
        // get an implicit DataModel wrapper at runtime

        // could be an array
        if (Signature.getArrayCount(valueType.getSignature())>0)
        {
            return createArraySymbol(symbolName, valueType.getSignature(), javaProject);
        }

        // if is a list, then we have extra work to do if it
        // is generic and has info about its contents
        if (valueType.isInstanceOf(TypeConstants.TYPE_LIST))
        {
            return createFromList(symbolName, valueType, javaProject);
        }
        // if is JSTL ResultSet, java ResultSet or DataModel
        // return the default symbol -- in the absence of definite
        // template info, these row containers are opaque to us
        else if (valueType.isInstanceOf(TypeConstants.TYPE_JAVAX_SERVLET_JSP_JSTL_SQL_RESULT)
                || valueType.isInstanceOf(TypeConstants.TYPE_RESULT_SET)
                || valueType.isInstanceOf(TypeConstants.TYPE_DATA_MODEL))
        {
            return createDefaultSymbol(symbolName);
        }
            
        // in other cases, we assume that the value is an explicit single row
        // scalar object
        return createScalarSymbol(symbolName, valueType.getSignature(), javaProject);
    }

    /**
     * @param symbolName The name of the symbol to create. Must not be null.
     * @param valueType The value expression representing the implicit list.  The signature
     * on the valueType must be a list. Must not be null.
     * @param javaProject The JavaProject whose classpath will be used to resolve types.  Must not be null.
     * 
     * @return a symbol that approximates as best as possible an implicit DataModel for java.util.List value expressions.  If the List has
     * resolvable Java 5 type arguments, then a scalar symbol will be created
     * using this type information.  If it is a raw type, then 
     * createDefaultSymbol() is called
     */
    protected final ISymbol createFromList(String symbolName, ValueType valueType, IJavaProject javaProject) 
    {
        assert symbolName != null;
        assert valueType != null;
        assert javaProject != null;
        assert TypeConstants.TYPE_LIST.equals(valueType.getSignature());
        
        final String[] typeArguments = valueType.getTypeArguments();
        
        if (typeArguments != null && typeArguments.length > 0)
        {
            // a list has a single type argument
            final String typeArg = typeArguments[0];

            if (Signature.getTypeSignatureKind(typeArg) == Signature.CLASS_TYPE_SIGNATURE)
            {
                return createScalarSymbol(symbolName, typeArg, javaProject);
            }
        }
        
        // if no resolvable type signatures, do the default thing
        return createDefaultSymbol(symbolName);
    }


    /**
     * @param symbolName The name of the symbol to create. Must not be null.
     * @param signature The fully resolved type signature of the scalar.  Must not be null.
     * @param javaProject The JavaProject whose classpath is to be used to resolve type information for signture. Must not be null.
     * @return a symbol approximating a scalar object DataModel wrapper.  The row variable for the
     * data model becomes of type signature
     */
    protected final ISymbol createScalarSymbol(final String symbolName, final String signature, final IJavaProject javaProject)
    {
        assert symbolName != null;
        assert signature != null;
        assert javaProject != null;

        final String elementType = Signature.getElementType(signature);
        
        IJavaTypeDescriptor2 desc = 
            SymbolFactory.eINSTANCE.createIJavaTypeDescriptor2();
        final int arrayCount = Signature.getArrayCount(signature);
        if (arrayCount > 0)
        {
            desc.setArrayCount(arrayCount);
        }
        
        IType type = TypeUtil.resolveType(javaProject, elementType);
        if (type != null)
        {
            desc.setType(type);
        }
        else
        {
            desc.setTypeSignatureDelegate(Signature.getTypeErasure(signature));
        }
        desc.getTypeParameterSignatures().addAll(Arrays.asList(Signature.getTypeArguments(signature)));

        IComponentSymbol symbol = SymbolFactory.eINSTANCE.createIComponentSymbol();
        symbol.setName(symbolName);
        symbol.setTypeDescriptor(desc);
        symbol.setRuntimeSource(ERuntimeSource.TAG_INSTANTIATED_SYMBOL_LITERAL);
        return symbol;
    }
   
    /**
     * @param symbolName The name of the symbol to create.  Must not be null
     * @return a default symbol that eliminates bogus warnings for this dataTable's
     * row variable in cases where something better is resolvable.  Note that this is
     * not ideal, since will result in any property being accepted on the variable with
     * this name.
     */
    public final ISymbol createDefaultSymbol(final String symbolName)
    {
        assert symbolName != null;
        
        final IMapTypeDescriptor typeDesc = 
            SymbolFactory.eINSTANCE.createIBoundedMapTypeDescriptor();
        // empty map source
        typeDesc.setMapSource(new HashMap());
        final IComponentSymbol symbol = 
            SymbolFactory.eINSTANCE.createIComponentSymbol();
        symbol.setName(symbolName);
        symbol.setTypeDescriptor(typeDesc);
        symbol.setDetailedDescription(Messages.getString("AbstractDataModelVariableFactory.DataModel.Symbol.RowVariable.DetailedDescription")); //$NON-NLS-1$
        symbol.setRuntimeSource(ERuntimeSource.TAG_INSTANTIATED_SYMBOL_LITERAL);
        return symbol;
    }
    
    /**
     * @param dataTableElement the DOM element that has a "value" attribute.
     * Must not be null.
     * @return the el text from the 'value attribute of a dataTable element
     * or null if not found
     */
    protected static String getELText(final Element dataTableElement)
    {
        assert dataTableElement != null;
        String attrVal = dataTableElement.getAttribute(IJSFConstants.ATTR_VALUE);
        
        if (attrVal != null)
        {
            return AppConfigValidationUtil.extractELExpression(attrVal).getElText();
        }
        return null;
    }
    
    /**
     * @return the variable source name.  Protects against null in the abstract method
     */
    protected final String internalGetVariableSourceName()
    {
        String variableSourceName = getVariableSourceName();
        
        if (variableSourceName == null)
        {
            JSFCorePlugin.log("Missing variableSourceName", new Throwable()); //$NON-NLS-1$
            return "**missing variable source name**"; //$NON-NLS-1$
        }
        
        return variableSourceName;
    }

    /**
     * @return a user displayable name for the source of variables created by this factory
     * Must not return null.
     */
    protected abstract String getVariableSourceName();
}
