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

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

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.history.AsOfClause;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.history.DecoratedDatabaseTable;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.querykeys.QueryKey;

/**
 * Superclass for all expression that have a context.
 * i.e. a base expression.
 */
public abstract class DataExpression extends BaseExpression {
    protected List<Expression> derivedTables;
    protected List<Expression> derivedFields;
    protected boolean hasBeenNormalized;
    protected TableAliasLookup tableAliases;
    protected AsOfClause asOfClause;

    /**
     * DataExpression constructor comment.
     */
    protected DataExpression() {
        super();
    }

    /**
     * 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 object) {
        if (this == object) {
            return true;
        }
        if (!super.equals(object)) {
            return false;
        }
        DataExpression expression = (DataExpression) object;
        return ((this.baseExpression == expression.getBaseExpression()) || ((this.baseExpression != null) && this.baseExpression.equals(expression.getBaseExpression())))
            && ((getAsOfClause() == expression.getAsOfClause()) || ((getAsOfClause() != null) && getAsOfClause().equals(expression.getAsOfClause())));
    }

    public void addDerivedField(Expression addThis) {
        if (derivedFields == null) {
            derivedFields = new ArrayList();
        }
        derivedFields.add(addThis);
    }

    public void addDerivedTable(Expression addThis) {
        if (derivedTables == null) {
            derivedTables = new ArrayList();
        }
        derivedTables.add(addThis);
    }

    @Override
    public Expression asOf(AsOfClause clause) {
        asOfClause = clause;
        return this;
    }

    /**
     * INTERNAL:
     * Find the alias for a given table
     */
    @Override
    public DatabaseTable aliasForTable(DatabaseTable table) {
        if (tableAliases == null) {
            if (this.baseExpression == null) {
                return null;
            }
            return this.baseExpression.aliasForTable(table);
        }

        return tableAliases.keyAtValue(table);
    }

    /**
     * INTERNAL:
     * Alias a particular table within this node
     */
    @Override
    protected void assignAlias(String name, DatabaseTable table) {
        if (!getBuilder().getSession().getProject().hasGenericHistorySupport()) {
            assignAlias(new DecoratedDatabaseTable(name, getAsOfClause()), table);
        } else {
            assignAlias(new DatabaseTable(name), table);
        }
    }

    /**
     * INTERNAL:
     * Alias a particular table within this node
     */
    protected void assignAlias(DatabaseTable alias, DatabaseTable table) {
        if (tableAliases == null) {
            tableAliases = new TableAliasLookup();
        }
        tableAliases.put(alias, table);
    }

    /**
     * INTERNAL:
     */
    public void clearAliases() {
        tableAliases = null;
    }

    public List<Expression> copyCollection(List<Expression> in, Map alreadyDone) {
        if (in == null) {
            return null;
        }
        List<Expression> result = new ArrayList(in.size());
        for (Expression exp : in) {
            result.add(exp.copiedVersionFrom(alreadyDone));
        }
        return result;
    }

    /**
     * INTERNAL:
     */
    public Expression existingDerivedField(DatabaseField field) {
        if (this.derivedFields == null) {
            return null;
        }
        for (Expression exp : this.derivedFields) {
            if (((FieldExpression)exp).getField().equals(field)) {
                return exp;
            }
        }
        return null;

    }

    /**
     * INTERNAL:
     */
    public Expression existingDerivedTable(DatabaseTable table) {
        if (this.derivedTables == null) {
            return null;
        }
        for (Expression exp : this.derivedTables) {
            if (((TableExpression)exp).getTable().equals(table)) {
                return exp;
            }
        }
        return null;

    }

    /**
     * INTERNAL:
     * Return the field appropriately aliased
     */
    public DatabaseField getAliasedField() {
        return null;
    }

    @Override
    public AsOfClause getAsOfClause() {
        return asOfClause;
    }

    public ClassDescriptor getDescriptor() {
        return null;
    }

    /**
     * INTERNAL:
     */
    public DatabaseField getField() {
        return null;
    }

    @Override
    public Expression getField(String fieldName) {
        DatabaseField field = new DatabaseField(fieldName);
        return getField(field);
    }

    @Override
    public Expression getField(DatabaseField field) {
        Expression existing = existingDerivedField(field);
        if (existing != null) {
            return existing;
        }
        return newDerivedField(field);
    }

    /**
     * INTERNAL:
     * Return the descriptor which contains this query key.
     */
    public ClassDescriptor getContainingDescriptor() {
        return ((DataExpression)this.baseExpression).getDescriptor();
    }

    public DatabaseMapping getMapping() {
        if (this.baseExpression == null) {
            return null;
        }
        ClassDescriptor descriptor = getContainingDescriptor();
        if (descriptor == null) {
            return null;
        }
        return descriptor.getObjectBuilder().getMappingForAttributeName(getName());
    }

    public QueryKey getQueryKeyOrNull() {
        return null;
    }

    @Override
    public Expression getTable(String tableName) {
        DatabaseTable table = new DatabaseTable(tableName);
        return getTable(table);
    }

    @Override
    public Expression getTable(DatabaseTable table) {
        Expression existing = existingDerivedTable(table);
        if (existing != null) {
            return existing;
        }
        return newDerivedTable(table);

    }

    /**
     * INTERNAL:
     * Return the aliases used.  For CR#2456 must never lazily initialize as also used for Expression identity.
     */
    @Override
    public TableAliasLookup getTableAliases() {
        return tableAliases;

    }

    /**
     * INTERNAL:
     * Did the normalizer already add additional joins to the where clause due to
     * this query key representing a foreign reference mapping?
     * This insures that join criteria (for any query key expression) is not
     * added twice.
     * <p>
     * New meaning: DataExpressions are often iterated on multiple times during
     * normalize, but Function/Relation expressions only once.  Adding a has
     * been normalized flag improves performance and is required in some
     * applications, such as have temporal query criteria been added.
     */
    public boolean hasBeenNormalized() {
        return hasBeenNormalized;
    }

    @Override
    public boolean hasAsOfClause() {
        return ((getAsOfClause() != null) && (getAsOfClause().getValue() != null));
    }

    @Override
    public boolean hasBeenAliased() {
        return ((tableAliases != null) && (tableAliases.size() != 0));

    }

    protected boolean hasDerivedFields() {
        return derivedFields != null;
    }

    protected boolean hasDerivedTables() {
        return derivedTables != null;
    }

    /**
     * INTERNAL:
     */
    public boolean isAttribute() {
        return false;
    }

    @Override
    public boolean isDataExpression() {
        return true;
    }

    /**
     * INTERNAL:
     * For iterating using an inner class
     */
    @Override
    public void iterateOn(ExpressionIterator iterator) {
        super.iterateOn(iterator);
        if (baseExpression != null) {
            baseExpression.iterateOn(iterator);
        }
    }

    /**
     * INTERNAL:
     */
    public Expression newDerivedField(DatabaseField field) {
        FieldExpression result = new FieldExpression(field, this);
        addDerivedField(result);
        return result;
    }

    /**
     * INTERNAL:
     */
    public Expression newDerivedTable(DatabaseTable table) {
        TableExpression result = new TableExpression(table);
        result.setBaseExpression(this);
        addDerivedTable(result);
        return result;
    }

    /**
     * ADVANCED: Return an expression representing a sub-select in the from clause.
     * <p> Example:
     * <pre>
     *  builder.getAlias(builder.subQuery(reportQuery)).get("type").equal("S");
     * </pre>
     */
    @Override
    public Expression getAlias(Expression subSelect) {
        TableExpression result = new FromSubSelectExpression((SubSelectExpression)subSelect);
        result.setBaseExpression(this);
        return result;
    }

    /**
     * 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 (this.hasBeenNormalized) {
            return this;
        }
        this.hasBeenNormalized = true;
        if (this.baseExpression != null) {
            // First normalize the base.
            setBaseExpression(this.baseExpression.normalize(normalizer));
            if (getAsOfClause() == null) {
                asOf(this.baseExpression.getAsOfClause());
            }
        }

        return super.normalize(normalizer);
    }

    /**
     * INTERNAL:
     * Used for cloning.
     */
    @Override
    protected void postCopyIn(Map alreadyDone) {
        super.postCopyIn(alreadyDone);
        clearAliases();
        this.derivedFields = copyCollection(this.derivedFields, alreadyDone);
        this.derivedTables = copyCollection(this.derivedTables, alreadyDone);
    }

    /**
     * INTERNAL:
     * Print SQL onto the stream, using the ExpressionPrinter for context
     */
    @Override
    public void printSQL(ExpressionSQLPrinter printer) {
        printer.printField(getAliasedField());
    }

    public void setHasBeenNormalized(boolean value) {
        hasBeenNormalized = value;
    }

    /**
     * INTERNAL:
     * For CR#2456, Table identity involves having two tables sharing the same
     * aliasing table.
     */
    public void setTableAliases(TableAliasLookup tableAliases) {
        if (this.tableAliases == null) {
            this.tableAliases = tableAliases;
        }
    }

    public String tableAliasesDescription() {
        if (tableAliases == null) {
            return "";
        }
        return tableAliases.toString();
    }

    /**
     * Print the base for debuggin purposes.
     */
    @Override
    public void writeSubexpressionsTo(BufferedWriter writer, int indent) throws IOException {
        if (this.baseExpression != null) {
            this.baseExpression.toString(writer, indent);
        }
    }
}
