/*******************************************************************************
 * 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.expressions;

import java.io.*;
import java.util.*;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.history.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.internal.databaseaccess.*;

/**
 * Abstract class for expression that have exactly two children, such as and/or and relations.
 */
public abstract class CompoundExpression extends Expression {
    protected ExpressionOperator operator;
    protected transient ExpressionOperator platformOperator;
    protected Expression firstChild;
    protected Expression secondChild;
    protected ExpressionBuilder builder;

    public CompoundExpression() {
        super();
    }
    
    /**
     * INTERNAL:
     * Return if the expression is equal to the other.
     * This is used to allow dynamic expression's SQL to be cached.
     */
    public boolean equals(Object object) {
        if (this == object) {
            return true;
        }
        if (!super.equals(object)) {
            return false;
        }
        CompoundExpression expression = (CompoundExpression) object;
        return ((this.operator == expression.operator) || ((this.operator != null) && this.operator.equals(expression.operator)))
            && ((this.firstChild == expression.firstChild) || ((this.firstChild != null) && this.firstChild.equals(expression.firstChild)))
            && ((this.secondChild == expression.secondChild) || ((this.secondChild != null) && this.secondChild.equals(expression.secondChild)));
    }
        
    /**
     * INTERNAL:
     * Compute a consistent hash-code for the expression.
     * This is used to allow dynamic expression's SQL to be cached.
     */
    public int computeHashCode() {
        int hashCode = super.computeHashCode();
        if (this.operator != null) {
            hashCode = hashCode + this.operator.hashCode();
        }
        if (this.firstChild != null) {
            hashCode = hashCode + this.firstChild.hashCode();
        }
        if (this.secondChild != null) {
            hashCode = hashCode + this.secondChild.hashCode();
        }
        return hashCode;
    }

    /**
     * INTERNAL:
     * Find the alias for a given table from the first or second child in the additionalOuterJoinCriteria
     */
    public DatabaseTable aliasForTable(DatabaseTable table) {
        DatabaseTable alias = null;
        if (this.firstChild != null) {
            alias = this.firstChild.aliasForTable(table);
        }

        if ((alias == null) && (this.secondChild != null)) {
            alias = this.secondChild.aliasForTable(table);
        }

        return alias;
    }

    public Expression asOf(AsOfClause clause) {
        final AsOfClause finalClause = clause;
        ExpressionIterator iterator = new ExpressionIterator() {
            public void iterate(Expression each) {
                if (each.isDataExpression()) {
                    each.asOf(finalClause);
                }
            }

            public boolean shouldIterateOverSubSelects() {
                return true;
            }
        };
        iterator.iterateOn(this);
        return this;
    }

    /**
     * INTERNAL:
     */
    public Expression create(Expression base, Object singleArgument, ExpressionOperator operator) {
        setFirstChild(base);
        Expression argument = Expression.from(singleArgument, base);
        setSecondChild(argument);
        setOperator(operator);
        return this;
    }

    /**
     * INTERNAL:
     */
    @Override
    public Expression create(Expression base, List arguments, ExpressionOperator operator) {
        setFirstChild(base);
        if (!arguments.isEmpty()) {
            setSecondChild((Expression)arguments.get(0));
        }
        setOperator(operator);
        return this;
    }

    /**
     * INTERNAL:
     * Used for debug printing.
     */
    public String descriptionOfNodeType() {
        return "Compound Expression";
    }

    /**
     * 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)
     */
    public ExpressionBuilder getBuilder() {
        // PERF: Cache builder.
        if (this.builder == null) {
            this.builder = this.firstChild.getBuilder();
            if (this.builder == null) {
                this.builder = this.secondChild.getBuilder();
            }
        }
        return this.builder;
    }

    public Expression getFirstChild() {
        return firstChild;
    }

    public ExpressionOperator getOperator() {
        return operator;
    }

    public ExpressionOperator getPlatformOperator(DatabasePlatform platform) {
        if (platformOperator == null) {
            initializePlatformOperator(platform);
        }
        return platformOperator;
    }

    public Expression getSecondChild() {
        return secondChild;
    }

    /**
     * INTERNAL:
     */
    public void initializePlatformOperator(DatabasePlatform platform) {
        if (this.operator.isComplete()) {
            platformOperator = this.operator;
            return;
        }
        platformOperator = platform.getOperator(this.operator.getSelector());
        if (platformOperator == null) {
            throw QueryException.invalidOperator(this.operator.toString());
        }
    }

    public boolean isCompoundExpression() {
        return true;
    }

    /**
     * INTERNAL:
     * For iterating using an inner class
     */
    public void iterateOn(ExpressionIterator iterator) {
        super.iterateOn(iterator);
        if (this.firstChild != null) {
            this.firstChild.iterateOn(iterator);
        }
        if (this.secondChild != null) {
            this.secondChild.iterateOn(iterator);
        }
    }

    /**
     * INTERNAL:
     * Normalize into a structure that is printable.
     * Also compute printing information such as outer joins.
     */
    public Expression normalize(ExpressionNormalizer normalizer) {
        validateNode();
        boolean previous = normalizer.isAddAdditionalExpressionsWithinCurrrentExpressionContext();
        boolean isOrExpression = (isLogicalExpression() && this.operator.getSelector() == ExpressionOperator.Or);
        normalizer.setAddAdditionalExpressionsWithinCurrrentExpressionContext(previous|| isOrExpression);
        
        try {
            if (this.firstChild != null) {
                //let's make sure a session is available in the case of a parallel expression
                ExpressionBuilder builder = this.firstChild.getBuilder();
                if (builder != null){
                    builder.setSession(normalizer.getSession().getRootSession(null));
                }
                setFirstChild(normalizer.processAdditionalLocalExpressions(this.firstChild.normalize(normalizer), isOrExpression));
            }
            if (this.secondChild != null) {
                //let's make sure a session is available in the case of a parallel expression
                 ExpressionBuilder builder = this.secondChild.getBuilder();
                 if (builder != null){
                     builder.setSession(normalizer.getSession().getRootSession(null));
                 }
                setSecondChild(normalizer.processAdditionalLocalExpressions(this.secondChild.normalize(normalizer), isOrExpression));
            }
        } finally {
            normalizer.setAddAdditionalExpressionsWithinCurrrentExpressionContext(previous);
        }

        // For CR2456, it is now possible for normalize to remove redundant
        // conditions from the where clause.
        if (this.firstChild == null) {
            return this.secondChild;
        } else if (this.secondChild == null) {
            return this.firstChild;
        }
        return this;
    }
    
    /**
     * Do any required validation for this node. Throw an exception if it's incorrect.
     * Ensure that both sides are not data expressions.
     */
    public void validateNode() {
        if (this.firstChild != null) {
            if (this.firstChild.isDataExpression() || this.firstChild.isConstantExpression()) {
                throw QueryException.invalidExpression(this);
            }
        }
        if (this.secondChild != null) {
            if (this.secondChild.isDataExpression() || this.secondChild.isConstantExpression()) {
                throw QueryException.invalidExpression(this);
            }
        }
    }

    /**
     * INTERNAL:
     * Used for cloning.
     */
    protected void postCopyIn(Map alreadyDone) {
        super.postCopyIn(alreadyDone);
        if (this.firstChild != null) {
            setFirstChild(this.firstChild.copiedVersionFrom(alreadyDone));
        }
        if (this.secondChild != null) {
            setSecondChild(this.secondChild.copiedVersionFrom(alreadyDone));
        }
    }

    /**
     * INTERNAL:
     * Print SQL
     */
    public void printSQL(ExpressionSQLPrinter printer) {
        ExpressionOperator realOperator = getPlatformOperator(printer.getPlatform());
        printer.printString("(");
        realOperator.printDuo(this.firstChild, this.secondChild, printer);
        printer.printString(")");
    }

    /**
     * INTERNAL:
     * Print java for project class generation
     */
    public void printJava(ExpressionJavaPrinter printer) {
        ExpressionOperator realOperator = getPlatformOperator(printer.getPlatform());
        realOperator.printJavaDuo(this.firstChild, this.secondChild, printer);
    }

    /**
     * INTERNAL:
     * This expression is built on a different base than the one we want. Rebuild it and
     * return the root of the new tree
     */
    public Expression rebuildOn(Expression newBase) {
        Vector arguments;

        Expression first = this.firstChild.rebuildOn(newBase);
        if (this.secondChild == null) {
            arguments = NonSynchronizedVector.newInstance(0);
        } else {
            arguments = NonSynchronizedVector.newInstance(1);
            arguments.add(this.secondChild.rebuildOn(newBase));
        }
        return first.performOperator(this.operator, arguments);
    }

    /**
     * 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.
     */
    public void resetPlaceHolderBuilder(ExpressionBuilder queryBuilder){
        this.firstChild.resetPlaceHolderBuilder(queryBuilder);
        if (this.secondChild != null){
            this.secondChild.resetPlaceHolderBuilder(queryBuilder);
        }
    }

    protected void setFirstChild(Expression firstChild) {
        this.firstChild = firstChild;
        this.builder = null;
    }

    public void setOperator(ExpressionOperator newOperator) {
        operator = newOperator;
    }

    protected void setSecondChild(Expression secondChild) {
        this.secondChild = secondChild;
        this.builder = null;
    }

    /**
     * INTRENAL:
     * Used to change an expression off of one base to an expression off of a different base.
     * i.e. expression on address to an expression on an employee's address.
     */
    @Override
    public Expression twistedForBaseAndContext(Expression newBase, Expression context, Expression oldBase) {
        Vector arguments;

        if (this.secondChild == null) {
            arguments = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(0);
        } else {
            arguments = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(1);
            arguments.addElement(this.secondChild.twistedForBaseAndContext(newBase, context, oldBase));
        }

        Expression first = this.firstChild.twistedForBaseAndContext(newBase, context, oldBase);
        return first.performOperator(this.operator, arguments);
    }

    /**
     * INTERNAL:
     * Used to print a debug form of the expression tree.
     */
    public void writeDescriptionOn(BufferedWriter writer) throws IOException {
        writer.write(operator.toString());
    }

    /**
     * INTERNAL:
     * Used for toString for debugging only.
     */
    public void writeSubexpressionsTo(BufferedWriter writer, int indent) throws IOException {
        if (this.firstChild != null) {
            this.firstChild.toString(writer, indent);
        }
        if (this.secondChild != null) {
            this.secondChild.toString(writer, indent);
        }
    }
    
    /**
     * INTERNAL:
     * Clear the builder when cloning.
     */
    public Expression shallowClone() {
        CompoundExpression clone = (CompoundExpression)super.shallowClone();
        clone.builder = null;
        return clone;
    }
}
