/*
 * 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.expressions;

import java.io.BufferedWriter;
import java.io.IOException;
import java.util.Map;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.history.AsOfClause;
import org.eclipse.persistence.internal.expressions.ExpressionJavaPrinter;
import org.eclipse.persistence.internal.expressions.ExpressionNormalizer;
import org.eclipse.persistence.internal.expressions.ObjectExpression;
import org.eclipse.persistence.internal.expressions.SQLSelectStatement;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.ReadQuery;

/**
 * <P>
 * <B>Purpose</B>: Allow for instances of expression to be created. Expressions are Java object-level representations of SQL "where" clauses.
 * The expressions attempt to mirror Java code as closely as possible.</p>
 *
 * <P>
 *
 * <B>Example</B>:
 * <BLOCKQUOTE><PRE>
 *        ExpressionBuilder employee = new ExpressionBuilder();
 *        employee.get("firstName").equal("Bob").and(employee.get("lastName").equal("Smith"))
 *
 *        {@literal >>} equivalent Java code: (employee.getFirstName().equals("Bob")) {@literal &&} (employee.getLastName().equals("Smith"))
 *
 *        {@literal >>} equivalent SQL: (F_NAME = 'Bob') AND (L_NAME = 'Smith')
 * </PRE></BLOCKQUOTE>
 *
 * @see Expression
 */
public class ExpressionBuilder extends ObjectExpression {
    protected transient AbstractSession session;
    protected Class<?> queryClass;
    protected SQLSelectStatement statement;
    protected DatabaseTable viewTable;
    protected DatabaseTable aliasedViewTable;

    protected boolean wasQueryClassSetInternally = true;

    protected boolean wasAdditionJoinCriteriaUsed = false;

    /**
     * PUBLIC:
     * Create a new ExpressionBuilder.
     */
    public ExpressionBuilder() {
        super();
    }

    /**
     * ADVANCED:
     * Create a new ExpressionBuilder representing instances of the argument class.
     * This can be used for the purpose of parallel expressions.
     * This is a type of query that searches on the relationship between to un-related objects.
     */
    public ExpressionBuilder(Class<?> queryClass) {
        super();
        this.queryClass = queryClass;
        this.wasQueryClassSetInternally = false;
    }

    /**
     * INTERNAL:
     * Return if the expression is equal to the other.
     * This is used to allow dynamic expression's SQL to be cached.
     */
    @Override
    public boolean equals(Object expression) {
        if (this == expression) {
            return true;
        }
        // Return false for parallel expressions, as equality is unknown.
        return super.equals(expression) && ((getQueryClass() == null) && ((ExpressionBuilder)expression).getQueryClass() == null);
    }

    /**
     * INTERNAL: Find the alias for a given table. Handle the special case where we are bogus
     * and it should be aliased against our derived tables instead.
     */
    @Override
    public DatabaseTable aliasForTable(DatabaseTable table) {
        if (hasViewTable()) {
            return getAliasedViewTable();
        }

        if (doesNotRepresentAnObjectInTheQuery()) {
            for (Expression expression : this.derivedTables) {
                DatabaseTable result = expression.aliasForTable(table);
                if (result != null) {
                    return result;
                }
            }
        } else {
            return super.aliasForTable(table);
        }
        return null; // No alias found in the derived tables
    }

    /**
     * INTERNAL:
     * Assign aliases to any tables which I own. Start with t(initialValue),
     * and return the new value of  the counter , i.e. if initialValue is one
     * and I have tables ADDRESS and EMPLOYEE I will assign them t1 and t2 respectively, and return 3.
     */
    @Override
    public int assignTableAliasesStartingAt(int initialValue) {
        if (hasBeenAliased()) {
            return initialValue;
        }

        if (doesNotRepresentAnObjectInTheQuery()) {
            return initialValue;
        }

        // This block should be removed I think.
        // The only reason to clone might be to
        // preserve the qualifier, but aliases need
        // qualifiers?  That seems strange.
        // Also this will break AsOf queries.  By
        // inference if has view table the AliasTableLookup
        // will contain one table, and that will be the
        // table of the view...
        if (hasViewTable()) {
            DatabaseTable aliased = viewTable.clone();
            String alias = "t" + initialValue;
            aliased.setName(alias);
            assignAlias(alias, viewTable);
            aliasedViewTable = aliased;
            hasBeenAliased = true;
            return initialValue + 1;
        }
        return super.assignTableAliasesStartingAt(initialValue);
    }

    /**
     * INTERNAL:
     * Used for debug printing.
     */
    @Override
    public String descriptionOfNodeType() {
        return "Base";
    }

    /**
     * INTERNAL:
     * There are cases (which we might want to eliminate?) where the expression builder
     * doesn't actually correspond to an object to be read. Mostly this is the case where
     * it's a data query in terms of tables, and the builder is only there to provide a base.
     * It might be better to make tables able to serve as their own base, but it's very nice
     * to have a known unique, shared base. In the meantime, this
     * is a special case to make sure the builder doesn't get tables assigned.
     */
    public boolean doesNotRepresentAnObjectInTheQuery() {
        return (hasDerivedTables() && !hasDerivedFields() && !hasDerivedExpressions());
    }

    /**
     * INTERNAL:
     */
    public DatabaseTable getAliasedViewTable() {
        return aliasedViewTable;

    }

    /**
     * INTERNAL:
     * Return the expression builder which is the ultimate base of this expression, or
     * null if there isn't one (shouldn't happen if we start from a root)
     */
    @Override
    public ExpressionBuilder getBuilder() {
        return this;
    }

    /**
     * INTERNAL:
     * Only usable after the session and class have been set. Return the
     * descriptor for the class this node represents.
     */
    @Override
    public ClassDescriptor getDescriptor() {
        if (descriptor == null) {
            if (getQueryClass() == null) {
                return null;
            } else {
                if (getSession() == null) {
                    throw QueryException.noExpressionBuilderFound(this);
                }
                descriptor = getSession().getDescriptor(getQueryClass());
                descriptor = convertToCastDescriptor(descriptor, getSession());
            }
        }
        return descriptor;

    }

    /**
     * INTERNAL:
     */
    public Class<?> getQueryClass() {
        return queryClass;
    }

    /**
     * INTERNAL:
     */
    @Override
    public AbstractSession getSession() {
        return session;
    }

    /**
     * INTERNAL:
     * Return the statement that expression is for.
     * This is used for the context in subselects.
     */
    public SQLSelectStatement getStatement() {
        return statement;
    }

    /**
     * INTERNAL:
     */
    public DatabaseTable getViewTable() {
        return viewTable;
    }

    /**
     * INTERNAL:
     */
    public boolean hasViewTable() {
        return viewTable != null;
    }

    /**
     * INTERNAL:
     */
    @Override
    public boolean isExpressionBuilder() {
        return true;
    }

    /**
     * INTERNAL:
     * Normalize the expression into a printable structure.
     * Any joins must be added to form a new root.
     */
    @Override
    public Expression normalize(ExpressionNormalizer normalizer) {
        if (hasBeenNormalized()) {
            return this;
        } else {
            setHasBeenNormalized(true);
        }

        // Normalize the ON clause if present.  Need to use rebuild, not twist as parameters are real parameters.
        if (this.onClause != null) {
            this.onClause = this.onClause.normalize(normalizer);
            if (shouldUseOuterJoin() || (!getSession().getPlatform().shouldPrintInnerJoinInWhereClause())) {
                normalizer.getStatement().addOuterJoinExpressionsHolders(this, null, null, null);
                if ((getDescriptor() != null) && (getDescriptor().getHistoryPolicy() != null)) {
                    Expression historyCriteria = getDescriptor().getHistoryPolicy().additionalHistoryExpression(this, this);
                    if (historyCriteria != null) {
                        normalizer.addAdditionalExpression(historyCriteria);
                    }
                }
            } else {
                normalizer.addAdditionalExpression(this.onClause);
            }
        }

        // This is required for parallel selects,
        // the session must be set and the additional join expression added.
        if (this.queryClass != null) {
            Expression criteria = null;

            setSession(normalizer.getSession().getRootSession(null));
            // The descriptor must be defined at this point.
            if (getDescriptor() == null) {
                throw QueryException.noExpressionBuilderFound(this);
            }
            if (!this.wasAdditionJoinCriteriaUsed) {
                criteria = getDescriptor().getQueryManager().getAdditionalJoinExpression();
                if (criteria != null) {
                    criteria = twist(criteria, this);
                }
            }

            if (isUsingOuterJoinForMultitableInheritance()) {
                if (getSession().getPlatform().shouldPrintOuterJoinInWhereClause()) {
                    Expression childrenCriteria = getDescriptor().getInheritancePolicy().getChildrenJoinExpression();
                    childrenCriteria = twist(childrenCriteria, this);
                    childrenCriteria.convertToUseOuterJoin();
                    if(criteria == null) {
                        criteria = childrenCriteria;
                    } else {
                        criteria = criteria.and(childrenCriteria);
                    }
                } else {
                    normalizer.getStatement().addOuterJoinExpressionsHolders(null, null, additionalExpressionCriteriaMap(), this.getDescriptor());
                    // fall through to the main case
                }
            }
            normalizer.addAdditionalExpression(criteria);


        }
        setStatement(normalizer.getStatement());
        if (getAsOfClause() == null) {
            asOf(AsOfClause.NO_CLAUSE);
        }
        if ((getDescriptor() != null) && (getDescriptor().getHistoryPolicy() != null)) {
            Expression temporalCriteria = getDescriptor().getHistoryPolicy().additionalHistoryExpression(this, this);
            normalizer.addAdditionalExpression(temporalCriteria);
        }

        ReadQuery query = normalizer.getStatement().getQuery();
        // Record any class used in a join to invalidate query results cache.
        if ((query != null) && query.shouldCacheQueryResults()) {
            if (this.queryClass != null) {
                query.getQueryResultsCachePolicy().getInvalidationClasses().add(this.queryClass);
            }
        }

        return this;
    }

    /**
     * INTERNAL:
     * Print java
     */
    @Override
    public void printJava(ExpressionJavaPrinter printer) {
        printer.printString(printer.getBuilderString());
    }

    /**
     * INTERNAL:
     * This expression is built on a different base than the one we want. Rebuild it and
     * return the root of the new tree
     * This assumes that the original expression has only a single builder.
     */
    @Override
    public Expression rebuildOn(Expression newBase) {
        return newBase;
    }

    /**
     * INTERNAL:
     * Search the tree for any expressions (like SubSelectExpressions) that have been
     * built using a builder that is not attached to the query.  This happens in case of an Exists
     * call using a new ExpressionBuilder().  This builder needs to be replaced with one from the query.
     */
    @Override
    public void resetPlaceHolderBuilder(ExpressionBuilder queryBuilder){
        return;
    }

    /**
     * INTERNAL:
     * Override Expression.registerIn to check if the new base expression
     * has already been provided for the clone.
     * @see org.eclipse.persistence.expressions.Expression#cloneUsing(Expression)
     */
    @Override
    protected Expression registerIn(Map alreadyDone) {
        // bug  2637484 INVALID QUERY KEY EXCEPTION THROWN USING BATCH READS AND PARALLEL EXPRESSIONS
        // Here do a special check to see if this a cloneUsing(newBase) call.
        Object value = alreadyDone.get(alreadyDone);
        if ((value == null) || (value == alreadyDone)) {
            // This is a normal cloning operation.
            return super.registerIn(alreadyDone);
        }
        ObjectExpression copy = (ObjectExpression)value;

        // copy is actually the newBase of a cloneUsing.
        alreadyDone.put(alreadyDone, alreadyDone);
        alreadyDone.put(this, copy);
        // Now need to copy over the derived expressions, etc.
        if (this.derivedExpressions != null) {
            if (copy.derivedExpressions == null) {
                copy.derivedExpressions = copyDerivedExpressions(alreadyDone);
            } else {
                copy.derivedExpressions.addAll(copyDerivedExpressions(alreadyDone));
            }
        }

        // Do the same for these protected fields.
        copy.postCopyIn(alreadyDone, this.derivedFields, this.derivedTables);
        return copy;
    }

    /**
     * INTERNAL:
     * Set the class which this node represents.
     */
    public void setQueryClass(Class<?> queryClass) {
        this.queryClass = queryClass;
        this.descriptor = null;
    }

    /**
     * INTERNAL:
     * Set the class and descriptor which this node represents.
     */
    public void setQueryClassAndDescriptor(Class<?> queryClass, ClassDescriptor descriptor) {
        this.queryClass = queryClass;
        this.descriptor = convertToCastDescriptor(descriptor, session);
    }

    /**
     * INTERNAL:
     * Set the session in which we expect this expression to be translated.
     * Stored session shall always be root session.
     */
    public void setSession(AbstractSession session) {
        if (session != null) {
            this.session = session.getRootSession(null);
        } else {
            this.session = null;
        }
    }

    /**
     * INTERNAL:
     * Set the statement that expression is for.
     * This is used for the context in subselects.
     */
    public void setStatement(SQLSelectStatement statement) {
        this.statement = statement;
    }

    /**
     * INTERNAL:
     * This expression represents something read through a view table.
     */
    public void setViewTable(DatabaseTable theTable) {
        viewTable = theTable;

    }

    /**
     * INTERNAL:
     * If the additional Join Criteria for the class this builder represents has
     * been added to the statement then mark this as true.  This will prevent
     * TopLink from adding it again at normalization
     */
    public void setWasAdditionJoinCriteriaUsed(boolean joinCriteriaUsed){
        this.wasAdditionJoinCriteriaUsed = joinCriteriaUsed;
    }

    /**
     * INTERNAL:
     * Rebuild myself against the base, with the values of parameters supplied by the context
     * expression. This is used for transforming a standalone expression (e.g. the join criteria of a mapping)
     * into part of some larger expression. You normally would not call this directly, instead calling twist
     * See the comment there for more details.
     */
    @Override
    public Expression twistedForBaseAndContext(Expression newBase, Expression context, Expression oldBase) {
        if (oldBase == null || this == oldBase) {
            return newBase;
        }
        return this;
    }

    /**
     * INTERNAL:
     * The expression builder represent the entire object, just return it.
     */
    @Override
    public Object valueFromObject(Object object, AbstractSession session, AbstractRecord translationRow, int valueHolderPolicy, boolean isObjectUnregistered) {
        return object;
    }

    /**
     * INTERNAL:
     * If the additional Join Criteria for the class this builder represents has
     * been added to the statement this method will return true;
     */
    public boolean wasAdditionJoinCriteriaUsed(){
        return this.wasAdditionJoinCriteriaUsed;
    }

    /**
     * INTERNAL:
     * Returns true if TopLink set the query class as opposed to the customer.  This
     * is important in determining if this Expression should be treated as a parallel
     * expression during normalization
     */
    public boolean wasQueryClassSetInternally(){
        return this.wasQueryClassSetInternally;
    }

    /**
     * INTERNAL:
     * Lookup the descriptor for this item by traversing its expression recursively.
     */
    @Override
    public ClassDescriptor getLeafDescriptor(DatabaseQuery query, ClassDescriptor rootDescriptor, AbstractSession session) {
        // The base case
        // The following special case is where there is a parallel builder
        // which has a different reference class as the primary builder.
        Class<?> queryClass = getQueryClass();
        if ((queryClass != null) && ((query == null) || (queryClass != query.getReferenceClass()))) {
           return convertToCastDescriptor( session.getDescriptor(queryClass), session);
        }
        return convertToCastDescriptor(rootDescriptor, session);//support casting
    }

    /**
     * INTERNAL:
     * For debug printing purposes.
     */
    @Override
    public void writeDescriptionOn(BufferedWriter writer) throws IOException {
        String className;
        if (getQueryClass() == null) {
            className = "QUERY OBJECT";
        } else {
            className = getQueryClass().getName();
        }
        writer.write(className + tableAliasesDescription());
    }
}
