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

import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.mappings.querykeys.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;

/**
 * This class represents a "query key" that isn't really there
 * in the descriptors. For example, I could use this to create
 * an 'employee' query key from an 'address' node even if addresses
 * don't know their employee. It's called manual, because I will
 * have to provide the relevant join criteria myself (normally based
 * on a reverse relationship. Motivated by batch reading.
 */
public class ManualQueryKeyExpression extends QueryKeyExpression {
    public ManualQueryKeyExpression() {
        super();
    }

    public ManualQueryKeyExpression(String impliedRelationshipName, Expression base) {
        super(impliedRelationshipName, base);
    }

    public ManualQueryKeyExpression(String impliedRelationshipName, Expression base, ClassDescriptor descriptor) {
        super(impliedRelationshipName, base);
        this.descriptor = descriptor;
    }

    /**
     * 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;
        }
        // Equality cannot easily be determined for maunal expressions.
        return false;
    }

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

    /**
     * INTERNAL:
     * If we ever get in the circumstance of a manual query key
     * to an aggregate, then we can assume that the owner of that
     * aggregate isn't participating (and even if it is, we can't
     * know which node it is, so *DO* use the aggregate's parents tables
     */
    @Override
    public List<DatabaseTable> getOwnedTables() {
        if (getDescriptor() == null) {
            return null;
        } else {
            if ((getDescriptor().getHistoryPolicy() != null) && (getAsOfClause().getValue() != null)) {
                return getDescriptor().getHistoryPolicy().getHistoricalTables();
            }
            return getDescriptor().getTables();
        }
    }

    @Override
    public QueryKey getQueryKeyOrNull() {
        return null;
    }

    /**
     * INTERNAL:
     * We can never be an attribute, we're always a join
     */
    @Override
    public boolean isAttribute() {
        return false;
    }

    @Override
    public Expression mappingCriteria(Expression base) {
        return null;
    }

    /**
     * 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) {
        ObjectExpression newLocalBase = (ObjectExpression)getBaseExpression().rebuildOn(newBase);
        return newLocalBase.getManualQueryKey(getName(), getDescriptor());
    }

    /**
     * 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) {
        ObjectExpression twistedBase = (ObjectExpression)getBaseExpression().twistedForBaseAndContext(newBase, context, oldBase);
        return twistedBase.getManualQueryKey(getName(), getDescriptor());

    }

    /**
     * Do any required validation for this node. Throw an exception if it's incorrect.
     */
    @Override
    public void validateNode() {
        // Override super.validateNode() because those criteria don't apply to us
    }
}
