/*
 * 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 java.io.*;
import java.util.*;

import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.expressions.*;

/**
 * A TableExpression allows for a raw database table to be referenced in a query.
 * This is used for ManyToMany and DirectCollection mappings to define their selection criteria.
 * It can also be used directly to mix SQL artifacts with Expressions.
 */
public class TableExpression extends DataExpression {
    protected DatabaseTable table;

    public TableExpression() {
        super();
    }

    public TableExpression(DatabaseTable table) {
        super();
        this.table = table;
    }

    /**
     * INTERNAL:
     * Alias a particular table within this node
     */
    @Override
    protected void assignAlias(DatabaseTable alias, DatabaseTable table) {
        if (this.baseExpression.isQueryKeyExpression()){
            QueryKeyExpression qkExpression = ((QueryKeyExpression)this.baseExpression);
            if (qkExpression.getTableAliases() != null && qkExpression.getTableAliases().keyAtValue(table) != null ) {
                return;
            }
        }
        super.assignAlias(alias, table);
    }

    /**
     * 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;
        }
        TableExpression expression = (TableExpression) object;
        return ((this.table == expression.table) || ((this.table != null) && this.table.equals(expression.table)));
    }

    /**
     * INTERNAL:
     * Compute a consistent hash-code for the expression.
     * This is used to allow dynamic expression's SQL to be cached.
     */
    @Override
    public int computeHashCode() {
        int hashCode = super.computeHashCode();
        if (getTable() != null) {
            hashCode = hashCode + getTable().hashCode();
        }
        return hashCode;
    }

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

    /**
     * INTERNAL:
     * Fully-qualify the databaseField if the table is known.
     * CR 3791
     */
    @Override
    public Expression getField(String fieldName) {
        // we need to check for full table qualification
        DatabaseField field = new DatabaseField(fieldName);
        if (!field.hasTableName()) {
            field.setTable(getTable());
        }
        return getField(field);
    }

    /**
     * INTERNAL:
     */
    @Override
    public List<DatabaseTable> getOwnedTables() {
        List<DatabaseTable> result = new ArrayList(1);
        result.add(getTable());
        return result;
    }

    public DatabaseTable getTable() {
        return table;
    }

    @Override
    public boolean isTableExpression() {
        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 (this.hasBeenNormalized) {
            return this;
        }
        // Bug4736461  Only setTableQualifier if getDatasourceLogin().getTableQualifier() is an empty string to make the window much smaller when
        // DatabaseTable.qualifiedName is reset
        if (getTable().getTableQualifier().length() == 0 && (normalizer.getSession().getDatasourceLogin().getTableQualifier().length() != 0)) {
            getTable().setTableQualifier(normalizer.getSession().getDatasourceLogin().getTableQualifier());
        }
        return super.normalize(normalizer);
    }

    /**
     * INTERNAL:
     * This expression is built on a different base than the one we want. Rebuild it and
     * return the root of the new tree
     */
    @Override
    public Expression rebuildOn(Expression newBase) {
        Expression newLocalBase = getBaseExpression().rebuildOn(newBase);
        return newLocalBase.getTable(getTable());
    }

    /**
     * INTERNAL:
     * Added for temporal querying.
     */
    public void setTable(DatabaseTable table) {
        this.table = table;
    }

    /**
     * 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) {
        Expression twistedBase = getBaseExpression().twistedForBaseAndContext(newBase, context, oldBase);
        return twistedBase.getTable(getTable());
    }

    /**
     * INTERNAL:
     * Used to print a debug form of the expression tree.
     */
    @Override
    public void writeDescriptionOn(BufferedWriter writer) throws IOException {
        writer.write(getTable().toString());
        writer.write(tableAliasesDescription());
    }
}
