/*******************************************************************************
 * Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/  
package org.eclipse.persistence.internal.jpa.parsing;

import java.util.*;

import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.internal.localization.*;
import org.eclipse.persistence.internal.sessions.AbstractSession;

/**
 * INTERNAL
 * <p><b>Purpose</b>: A ParseTree contains Node(s). This contains a root Node and provides traversal utilities.
 * <p><b>Responsibilities</b>:<ul>
 * <li> Add parameters to the query
 * <li> Generate an expression for the query
 * <li> Answer true if the tree has parameters
 * <li> Maintain the primary class name for the query
 * <li> Maintain the root of the parse tree
 * <li> Maintain the context for the parse tree
 * <li> Maintain the distinct state for the parse tree
 * <li> Print the contents of the parse tree on a string
 * </ul>
 *    @author Jon Driscoll and Joel Lucuik
 *    @since TopLink 4.0
 */
public class ParseTree {
    private ParseTreeContext context;
    private QueryNode queryNode;
    private FromNode fromNode;
    private SetNode setNode;
    private WhereNode whereNode;
    private OrderByNode orderByNode = null;
    private GroupByNode groupByNode = null;
    private HavingNode havingNode = null;
    private ClassLoader classLoader = null;
    private short distinctState = ObjectLevelReadQuery.UNCOMPUTED_DISTINCT;
    private boolean validated = false;
    private Set unusedVariables = null;

    /**
     * Return a new ParseTree.
     */
    public ParseTree() {
        super();
    }

    /**
     * INTERNAL
     * Returns a DatabaseQuery instance for this ParseTree.
     */
    public DatabaseQuery createDatabaseQuery() {
        return (queryNode == null) ? null :
            queryNode.createDatabaseQuery(context);
    }

    /**
      * INTERNAL
      * Adjust the reference class of the passed query if necessary
      *
      * Need to test this for Employee, employee.getAddress(), report query
      */
    public void adjustReferenceClassForQuery(DatabaseQuery theQuery, GenerationContext generationContext) {
        Class referenceClass = getReferenceClass(theQuery, generationContext);
        if ((referenceClass != null) && (referenceClass != theQuery.getReferenceClass())) {
            if (theQuery.isObjectLevelReadQuery()) {
                // The referenceClass needs to be changed.
                // This should only happen in an ejbSelect...
                ((ObjectLevelReadQuery)theQuery).setReferenceClass(referenceClass);
                generationContext.setBaseQueryClass(referenceClass);
                ((ObjectLevelReadQuery)theQuery).changeDescriptor(generationContext.getSession());
            } else if (theQuery.isUpdateAllQuery()) {
                ((UpdateAllQuery)theQuery).setReferenceClass(referenceClass);
            } else if (theQuery.isDeleteAllQuery()) {
                ((DeleteAllQuery)theQuery).setReferenceClass(referenceClass);
            }
        }
    }

    /**
     * INTERNAL
     * Initialize the base expression in the generation context.
     */
    public void initBaseExpression(ObjectLevelReadQuery theQuery, GenerationContext generationContext) {
        String variable = getFromNode().getFirstVariable();
        ParseTreeContext context = generationContext.getParseTreeContext();
        if (context.isRangeVariable(variable)) {
            Class referenceClass = theQuery.getReferenceClass();
            // Create a new expression builder for the reference class
            ExpressionBuilder builder = new ExpressionBuilder(referenceClass);
            // Use the expression builder as the default expression builder for the query
            theQuery.setExpressionBuilder(builder);
            // Add the expression builder to the expression cache in the context
            generationContext.setBaseExpression(variable, builder);
        } else {
            // Get the declaring node for the variable
            Node path = context.pathForVariable(variable);
            // Get the ExpressionBuilder of the range variable for the path
            Class baseClass = getBaseExpressionClass(path, generationContext);
            // and change the reference class accordingly
            theQuery.setReferenceClass(baseClass);
            theQuery.changeDescriptor(generationContext.getSession());
            generationContext.setBaseQueryClass(baseClass);
            // Set the node expression as base expression
            Expression baseExpression = path.generateExpression(generationContext);
            generationContext.setBaseExpression(variable, baseExpression);
            // Use the base ExpressionBuilder as the default for the query
            theQuery.setExpressionBuilder(baseExpression.getBuilder());
        }
    }

    /**
     * INTERNAL
     * Initialize the base expression in the generation context.
     */
    public void initBaseExpression(ModifyAllQuery theQuery, GenerationContext generationContext) {
        ModifyNode queryNode = (ModifyNode)getQueryNode();
        String variable = queryNode.getCanonicalAbstractSchemaIdentifier();
        Class referenceClass = theQuery.getReferenceClass();
        // Create a new expression builder for the reference class
        ExpressionBuilder builder = new ExpressionBuilder(referenceClass);
        // Use the expression builder as the default expression builder for the query
        theQuery.setExpressionBuilder(builder);
        // Add the expression builder to the expression cache in the context
        generationContext.setBaseExpression(variable, builder);        
    }
    
    /** */
    private Class getBaseExpressionClass(Node node, GenerationContext generationContext) {
        ParseTreeContext context = generationContext.getParseTreeContext();
        Class clazz = null;
        if (node == null) {
            clazz = null;
        } else if (node.isDotNode()) {
            // DotNode: delegate to left
            clazz = getBaseExpressionClass(node.getLeft(), generationContext);
        } else if (node.isVariableNode()) {
            // VariableNode
            String variable = ((VariableNode)node).getCanonicalVariableName();
            if (!context.isRangeVariable(variable)) {
                Node path = context.pathForVariable(variable);
                // Variable is defined in JOIN/IN clause => 
                // return the Class from its definition
                clazz = getBaseExpressionClass(path, generationContext);
            } else {
                // Variable is defined in range variable decl =>
                // return its class
                String schema = context.schemaForVariable(variable);
                if (schema != null) {
                    clazz = context.classForSchemaName(schema, generationContext);
                }
            }
        }
        return clazz;
    }

    /** 
     * INTERNAL
     * Validate the parse tree.
     */
    protected void validate(AbstractSession session, ClassLoader classLoader) {
        validate(new TypeHelperImpl(session, classLoader));
    }

    /** 
     * INTERNAL
     * Validate the parse tree.
     */
    public void validate(TypeHelper typeHelper) {
        ParseTreeContext context = getContext();
        context.setTypeHelper(typeHelper);
        validate(context);
    }
    
    /** 
     * INTERNAL
     * Validate the parse tree.
     */
    public void validate(ParseTreeContext context) {
        if (validated) {
            // already validated => return
            return;
        }
        
        validated = true;
        context.enterScope();
        if (fromNode != null) {
            fromNode.validate(context);
        }
        queryNode.validate(context);
        qualifyAttributeAccess(context);
        if (setNode != null) {
            setNode.validate(context);
        }
        if (whereNode != null) {
            whereNode.validate(context);
        }
        if (hasOrderBy()) {
            orderByNode.validate(context, (SelectNode)queryNode);
        }
        if (hasGroupBy()) {
            groupByNode.validate(context, (SelectNode)queryNode);
        }
        if (hasHaving()) {
            havingNode.validate(context, groupByNode);
        }
        // store the set od unused variable for later use
        unusedVariables = context.getUnusedVariables();
        context.leaveScope();
    }

    /** 
     * INTERNAL
     * This method handles any unqualified field access in bulk UPDATE and
     * DELETE statements. A UPDATE or DELETE statement may not define an
     * identification variable. In this case any field accessed from the
     * current class is not qualified with an identification variable, e.g.
     *   UPDATE Customer SET name = :newname
     * The method goes through the expressions of the SET clause and the WHERE
     * clause of such an DELETE and UPDATE statement and qualifies the field
     * access using the abstract schema name as qualifier.
     */
    protected void qualifyAttributeAccess(ParseTreeContext context) {
        if ((queryNode.isUpdateNode() || queryNode.isDeleteNode()) &&
            ((ModifyNode)queryNode).getAbstractSchemaIdentifier() == null) {
            if (setNode != null) {
                setNode.qualifyAttributeAccess(context);
            }
            if (whereNode != null) {
                whereNode.qualifyAttributeAccess(context);
            }
        }
    }

    /**
     * INTERNAL
     * Add the ordering to the passed query
     */
    public void addOrderingToQuery(ObjectLevelReadQuery theQuery, GenerationContext generationContext) {
        if (hasOrderBy()) {
            (getOrderByNode()).addOrderingToQuery(theQuery, generationContext);
        }
    }

    /**
     * INTERNAL
     * Add the grouping to the passed query
     */
    public void addGroupingToQuery(ObjectLevelReadQuery theQuery, GenerationContext generationContext) {
        if (hasGroupBy()) {
            (getGroupByNode()).addGroupingToQuery(theQuery, generationContext);
        }
    }

    /**
     * INTERNAL
     * Add the having to the passed query
     */
    public void addHavingToQuery(ObjectLevelReadQuery theQuery, GenerationContext generationContext) {
        if (hasHaving()) {
            (getHavingNode()).addHavingToQuery(theQuery, generationContext);
        }
    }

    /**
     * INTERNAL
     */
    public void addNonFetchJoinAttributes(ObjectLevelReadQuery theQuery, GenerationContext generationContext) {
        ParseTreeContext context = generationContext.getParseTreeContext();
        for (Iterator i = unusedVariables.iterator(); i.hasNext();) {
            String variable = (String)i.next();
            Expression expr = null;
            if (!context.isRangeVariable(variable)) {
                Node path = context.pathForVariable(variable);
                expr = path.generateExpression(generationContext);
                theQuery.addNonFetchJoinedAttribute(expr);
            } else {
                // Ignore, assume 'Select 1 from Employee e' or sorts
                // unused range variable => not supported yet
                //throw JPQLException.notYetImplemented(context.getQueryInfo(),
                //    "Variable [" + variable + "] is defined in a range variable declaration, but not used in the rest of the query.");
            }
        }
    }

    /**
     * INTERNAL
     * Add the updates to the passed query
     */
    public void addUpdatesToQuery(UpdateAllQuery theQuery, GenerationContext generationContext) {
        if (getSetNode() != null) {
            (getSetNode()).addUpdatesToQuery(theQuery, generationContext);
        }
    }

    /**
     * INTERNAL
     * Add parameters to the query
     */
    public void addParametersToQuery(DatabaseQuery query) {
        //Bug#4646580  Add arguments to query
        if (context.hasParameters()) {
            TypeHelper typeHelper = context.getTypeHelper();
            for (Iterator i = context.getParameterNames().iterator(); i.hasNext();) {
                String param = (String)i.next();
                Object type = context.getParameterType(param);
                Class clazz = typeHelper.getJavaClass(type);
                if (clazz == null) {
                    clazz = Object.class;
                }
                query.addArgument(param, clazz);
            }
        }
    }
    
    /**
     * INTERNAL
     * Apply the select or update to the passed query.
     * If there is a single attribute being selected, add it to the query result set
     * If an aggregate is being used, add it to the query result set
     */
    public void applyQueryNodeToQuery(DatabaseQuery theQuery, GenerationContext generationContext) {
        getQueryNode().applyToQuery(theQuery, generationContext);
    }

    /**
     * INTERNAL
     * Build the context to be used when generating the expression from the parse tree
     */
    public GenerationContext buildContext(DatabaseQuery query, AbstractSession sessionForContext) {
        if (query.isObjectLevelReadQuery()) {
            return buildContextForReadQuery(sessionForContext);
        } else if (query.isUpdateAllQuery() || query.isDeleteAllQuery()) {
            return new GenerationContext(getContext(), sessionForContext, this);
        }
        return null;
    }

    /**
     * INTERNAL
     * Build the context to be used when generating the expression from the parse tree
     */
    public GenerationContext buildContextForReadQuery(AbstractSession sessionForContext) {
        return new SelectGenerationContext(getContext(), sessionForContext, this);
    }

    /**
     * INTERNAL
     * Build a context for the expression generation
     */
    public Expression generateExpression(DatabaseQuery readQuery, GenerationContext generationContext) {
        Expression selectExpression = getQueryNode().generateExpression(generationContext);
        if (getWhereNode() == null) {
            return selectExpression;
        }
        Expression whereExpression = getWhereNode().generateExpression(generationContext);

        selectExpression = getQueryNode().generateExpression(generationContext);
        if (selectExpression != null) {
            whereExpression = selectExpression.and(whereExpression);
        }
        return whereExpression;
    }

    /**
     * Return the context for this parse tree
     */
    public ParseTreeContext getContext() {
        return context;
    }

    /**
     * INTERNAL
     * Return the FROM Node
     */
    public FromNode getFromNode() {
        return fromNode;
    }

    /**
     * INTERNAL
     * Return a class loader
     * @return java.lang.ClassLoader
     */
    public ClassLoader getClassLoader() {
        if (classLoader == null) {
            return org.eclipse.persistence.internal.helper.ConversionManager.getDefaultManager().getLoader();
        } else {
            return classLoader;
        }
    }

    /**
     * INTERNAL
     * Return the OrderByNode
     */
    public OrderByNode getOrderByNode() {
        return orderByNode;
    }

    /**
     * INTERNAL
     * Return the GroupByNode
     */
    public GroupByNode getGroupByNode() {
        return groupByNode;
    }

    /**
     * INTERNAL
     * Return the HavingNode
     */
    public HavingNode getHavingNode() {
        return havingNode;
    }

    /**
     * getReferenceClass(): Answer the class which will be the reference class for the query.
     * Resolve this using the node parsed from the "SELECT" of the EJBQL query string
     */
    public Class getReferenceClass(DatabaseQuery query, GenerationContext generationContext) {
        if (getQueryNode() == null) {
            return null;
        }
        return getQueryNode().getReferenceClass(generationContext);
    }

    /**
     * INTERNAL
     * Return the root node for the tree
     */
    public QueryNode getQueryNode() {
        return queryNode;
    }

    /**
     * INTERNAL
     * Return the set node for the tree
     */
    public SetNode getSetNode() {
        return setNode;
    }

    /**
     * INTERNAL
     * Return the Where node
     */
    public WhereNode getWhereNode() {
        return whereNode;
    }

    /**
     * INTERNAL
     * Return the DISTINCT state for the tree
     */
    public short getDistinctState() {
        return distinctState;
    }

    /**
     * INTERNAL
     * Does this EJBQL have an Ordering Clause
     */
    public boolean hasOrderBy() {
        return getOrderByNode() != null;
    }

    /**
     * INTERNAL
     * Does this EJBQL have a Grouping Clause
     */
    public boolean hasGroupBy() {
        return getGroupByNode() != null;
    }

    /**
     * INTERNAL
     * Does this EJBQL have a Having Clause
     */
    public boolean hasHaving() {
        return getHavingNode() != null;
    }

    /**
     * INTERNAL:
     * Set the class loader for this parse tree
     * @param loader 
     */
    public void setClassLoader(ClassLoader loader){
        this.classLoader = loader;
    }

    /**
     * INTERNAL
     * Set the context for this parse tree
     */
    public void setContext(ParseTreeContext newContext) {
        context = newContext;
    }

    /**
     * INTERNAL
     * Set the FROM node for the query
     */
    public void setFromNode(FromNode fromNode) {
        this.fromNode = fromNode;
    }

    /**
     * INTERNAL
     * Set the Order by node
     */
    public void setOrderByNode(OrderByNode newOrderByNode) {
        orderByNode = newOrderByNode;
    }

    /**
     * INTERNAL
     * Set the Group by node
     */
    public void setGroupByNode(GroupByNode newGroupByNode) {
        groupByNode = newGroupByNode;
    }

    /**
     * INTERNAL
     * Set the Having node
     */
    public void setHavingNode(HavingNode newHavingNode) {
        havingNode = newHavingNode;
    }

    public void setSelectionCriteriaForQuery(DatabaseQuery theQuery, GenerationContext generationContext) {
        theQuery.setSelectionCriteria(generateExpression(theQuery, generationContext));
    }

    /**
     * INTERNAL
     * Set the Select node
     */
    public void setQueryNode(QueryNode newQueryNode) {
        queryNode = newQueryNode;
    }

    /**
     * INTERNAL
     * Set the Where node
     */
    public void setSetNode(SetNode newSetNode) {
        setNode = newSetNode;
    }

    /**
     * INTERNAL
     * Set the Where node
     */
    public void setWhereNode(WhereNode newWhereNode) {
        whereNode = newWhereNode;
    }

    /**
     * INTERNAL
     * Set the DISTINCT state for the tree
     */
    public void setDistinctState(short newDistinctState) {
        distinctState = newDistinctState;
    }

    /**
     * INTERNAL
     * Print the contents of the parse tree on a string
     */
    public String toString() {
        StringBuffer buffer = new StringBuffer();
        buffer.append(getContext().toString());
        return ToStringLocalization.buildMessage("context", (Object[])null) + " " + buffer.toString();
    }

    /**
     * INTERNAL
     * Verify that the alias in the SELECT is valid.
     * Invalid: SELECT OBJECT(badAlias) FROM Employee employee....
     * Valid: SELECT OBJECT(employee) FROM Employee employee....
     */
    public void verifySelect(DatabaseQuery theQuery, GenerationContext generationContext) {
        if (theQuery.isObjectLevelReadQuery()) {
            //verify the selected alias,
            //this will throw an error if the alias is bad
            ((SelectNode)getQueryNode()).verifySelectedAlias(generationContext);
        }
    }

    /**
     * INTERNAL
     * Answer true if DISTINCT has been chosen.
     */
    public boolean usesDistinct() {
        return distinctState == ObjectLevelReadQuery.USE_DISTINCT;
    }
}
