/*
 * Copyright (c) 1998, 2020 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.expressions;

import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import java.util.*;

/**
 * This is used during the normalization process to allow for a single main expression traversal.
 */
public class ExpressionNormalizer {

    /** A new root expression can be made from joins being added to the original expression. */
    protected Expression additionalExpression;

    /** The statement being normalized. */
    protected SQLSelectStatement statement;

    /** Subselect expressions found in the course of normalization. */
    protected List<SubSelectExpression> subSelectExpressions;

    /** The session being normalized in. */
    protected AbstractSession session;

    /** Used to maintain identity of cloned expressions. */
    protected Map<Expression, Expression> clonedExpressions;

    /**
     * Used to trigger adding additional join operations etc to the expression being processed instead of at the end of the where clause.
     * Useful for dealing with Treat within an Or clause, as the type expression needs to be appended within the OR condition rather AND'd
     *  to the entire thing.
     */
    protected boolean addAdditionalExpressionsWithinCurrrentExpressionContext = false;
    /** Local expression from joins being added to the original expression. */
    protected Expression additionalLocalExpression;

    public ExpressionNormalizer(SQLSelectStatement statement) {
        this.statement = statement;
    }

    public Map<Expression, Expression> getClonedExpressions() {
        return clonedExpressions;
    }

    public void setClonedExpressions(Map<Expression, Expression> clonedExpressions) {
        this.clonedExpressions = clonedExpressions;
    }

    public void addAdditionalExpression(Expression theExpression) {
        // This change puts a null check into every call, but is printing additional
        // expressions in a meaningful order worth it?
        additionalExpression = (additionalExpression == null) ? theExpression : additionalExpression.and(theExpression);
    }

    /**
     * INTERNAL:
     * Remember this subselect so that it can be normalized after the enclosing
     * select statement is.
     */
    public void addSubSelectExpression(SubSelectExpression subSelectExpression) {
        if (this.subSelectExpressions == null) {
            this.subSelectExpressions = new ArrayList(4);
        }
        if (!this.subSelectExpressions.contains(subSelectExpression)) {
            this.subSelectExpressions.add(subSelectExpression);
        }
    }

    public Expression getAdditionalExpression() {
        return additionalExpression;
    }

    public AbstractSession getSession() {
        return session;
    }

    public SQLSelectStatement getStatement() {
        return statement;
    }

    /**
     * INTERNAL:
     * Were subselect expressions found while normalizing the selection criteria?
     * Assumes underlying collection is initialized on first add.
     */
    public boolean encounteredSubSelectExpressions() {
        return (subSelectExpressions != null);
    }

    /**
     * INTERNAL:
     * Normalize all subselect expressions found in the course of normalizing the
     * enclosing query.
     * This method allows one to completely normalize the parent statement first
     * (which should treat its sub selects as black boxes), and then normalize the
     * subselects (which require full knowledge of the enclosing statement).
     * This should make things clearer too,
     * Assumes encounteredSubSelectExpressions() true.
     * For CR#4223.
     */
    public void normalizeSubSelects(Map clonedExpressions) {
        for (SubSelectExpression next : this.subSelectExpressions) {
            next.normalizeSubSelect(this, clonedExpressions);
        }
    }

    public void setAdditionalExpression(Expression additionalExpression) {
        this.additionalExpression = additionalExpression;
    }

    public void setSession(AbstractSession session) {
        this.session = session;
    }

    public void setStatement(SQLSelectStatement statement) {
        this.statement = statement;
    }

    /**
     * Similar to addAdditionalExpression, this keeps a running expression used for joins so that they can be added locally within 'OR'
     * predicates rather than to the entire where clause.  If addAdditionalExpressionsWithinCurrrentExpressionContext is false, it will work
     * the same as addAdditionalExpression
     * @param theExpression
     */
    public void addAdditionalLocalExpression(Expression theExpression) {
        // This change puts a null check into every call, but is printing additional
        // expressions in a meaningful order worth it?
        if (addAdditionalExpressionsWithinCurrrentExpressionContext) {
            additionalLocalExpression = (additionalLocalExpression == null) ? theExpression : additionalLocalExpression.and(theExpression);
        } else {
            additionalExpression = (additionalExpression == null) ? theExpression : additionalExpression.and(theExpression);
        }
    }

    /**
     * INTERNAL
     * This will return the localExpression if isLogicalExpression is false, otherwise it will check the addAdditionalExpressionsWithinCurrrentExpressionContext
     * flag and clear additionalLocalExpression once adding it to the localExpression.
     * @param localExpression
     * @param isLogicalExpression
     * @return
     */
    public Expression processAdditionalLocalExpressions(Expression localExpression, boolean isLogicalExpression) {
        if (!isLogicalExpression || !addAdditionalExpressionsWithinCurrrentExpressionContext) {
            return localExpression;
        }
        Expression expToReturn = localExpression.and(additionalLocalExpression);
        additionalLocalExpression = null;

        return expToReturn;
    }

    public boolean isAddAdditionalExpressionsWithinCurrrentExpressionContext() {
        return addAdditionalExpressionsWithinCurrrentExpressionContext;
    }

    /**
     * INTERNAL:
     * Allows keeping track when the normalizer is within a logical OR statement, where additionalExpressions might need to be added to the local
     * expression instead of at the end of the where clause.
     * @param addAdditionalExpressionsWithinCurrrentExpressionContext
     */
    public void setAddAdditionalExpressionsWithinCurrrentExpressionContext(
            boolean addAdditionalExpressionsWithinCurrrentExpressionContext) {
        this.addAdditionalExpressionsWithinCurrrentExpressionContext = addAdditionalExpressionsWithinCurrrentExpressionContext;
    }
}
