/*
 * Copyright (c) 1998, 2021 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 v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.jpa.parsing;


// Java imports
import java.util.Hashtable;
import java.util.Set;

// TopLink imports
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.expressions.Expression;

/**
 * INTERNAL
 * <p><b>Purpose</b>: Maintain the generation context for an EJBQL query
 * <p><b>Responsibilities</b>:<ul>
 * <li> Maintain a table of expression builders and alias's
 * <li> Maintain the base query class
 * <li> Maintain a handle to the session
 * <li> Maintain a handle to the parse tree
 * </ul>
 *    @author Jon Driscoll and Joel Lucuik
 *    @since TopLink 4.0
 */
public class GenerationContext {
    protected AbstractSession session;
    protected ParseTreeContext parseTreeContext;
    protected Class<?> baseQueryClass;
    protected Expression baseExpression;
    protected Hashtable<String, Expression> expressions;
    protected ParseTree parseTree;
    protected boolean isNotIndicatedInMemberOf = false;

    //If a NOT MEMBER OF is encountered, we need to store the MEMBER OF
    //so that the right side of the member of can use the stored expression
    //from the left
    protected MemberOfNode memberOfNode = null;

    public GenerationContext() {
        super();
        expressions = new Hashtable<>();
    }

    public GenerationContext(ParseTreeContext newContext, AbstractSession newSession, ParseTree newParseTree) {
        this();
        parseTreeContext = newContext;
        session = newSession;
        parseTree = newParseTree;
    }

    public void addExpression(Expression expression, String aliasName) {
        expressions.put(aliasName, expression);
    }

    public Expression expressionFor(String aliasName) {
        Expression exp = expressions.get(aliasName);

        if (exp == null && (! expressions.isEmpty()) && isSelectGenerationContext()) {
            GenerationContext outerContext = ((SelectGenerationContext) this).getOuterContext();

            if (outerContext != null) {
                return outerContext.expressionFor(aliasName);
            }
        }

        return exp;
    }

    public Class<?> getBaseQueryClass() {
        return baseQueryClass;
    }

    public ParseTreeContext getParseTreeContext() {
        return parseTreeContext;
    }

    public ParseTree getParseTree() {
        return parseTree;
    }

    public AbstractSession getSession() {
        return session;
    }

    public void setBaseQueryClass(Class<?> newBaseQueryClass) {
        baseQueryClass = newBaseQueryClass;
    }

    /**
     * Caches the specified expression under the variable name for the base
     * query class.
     */
    public void setBaseExpression(String variable, Expression expr) {
        // Store the expression for faster access
        baseExpression = expr;

        // Store it into the cache
        addExpression(expr, variable);
    }

    /** */
    public Expression getBaseExpression() {
        return baseExpression;
    }

    public void setParseTree(ParseTree parseTree) {
        this.parseTree = parseTree;
    }

    public void setParseTreeContext(ParseTreeContext newParseTreeContext) {
        parseTreeContext = newParseTreeContext;
    }

    public void setSession(AbstractSession newSession) {
        session = newSession;
    }

    //Answer true if we need to use parallel expressions
    //This will be the case if a 1:1 is SELECTed in the EJBQL.
    public boolean useParallelExpressions() {
        return false;
    }

    //Answer true if we want VariableNodes to check if they're
    //SELECTed first, to determine how to instantiate the ExpressionBuilder
    public boolean shouldCheckSelectNodeBeforeResolving() {
        return false;
    }

    //Set and get the contained MemberOfNode. This is for handling NOT MEMBER OF.
    public void setMemberOfNode(MemberOfNode newMemberOfNode) {
        memberOfNode = newMemberOfNode;
    }

    public MemberOfNode getMemberOfNode() {
        return memberOfNode;
    }

    //Answer true if we have a MemberOfNode contained. This is for handling NOT MEMBER OF
    public boolean hasMemberOfNode() {
        return memberOfNode != null;
    }

    public boolean isSelectGenerationContext() {
        return false;
    }

    //Answer true if we should use outer joins in our get() (vs getAllowingNull())
    public boolean shouldUseOuterJoins() {
        return false;
    }

    /** */
    public Expression joinVariables(Set<String> variables) {
        return null;
    }
}
