/*
 * Copyright (c) 2011, 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:
//     10/26/2012-2.5 Chris Delahunt
//       - 350469: JPA 2.1 Criteria Query framework Bulk Update/Delete support
package org.eclipse.persistence.internal.jpa.querydef;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import jakarta.persistence.criteria.CommonAbstractCriteria;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.ParameterExpression;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import jakarta.persistence.criteria.Subquery;
import jakarta.persistence.metamodel.EntityType;
import jakarta.persistence.metamodel.Metamodel;

import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.internal.expressions.ConstantExpression;
import org.eclipse.persistence.queries.DatabaseQuery;

/**
 * <p>
 * <b>Purpose</b>: Contains the implementation of the CommonAbstractCriteria interface of
 * the JPA criteria API.
 * <p>
 * <b>Description</b>: This is the container class for the components that
 * define a query. This is the superclass of CriteriaQuery, SubQuery, CriteriaDelete
 * and CriteriaUpdate.
 *
 * @see jakarta.persistence.criteria CommonAbstractCriteria
 *
 * @author Chris Delahunt
 * @since EclipseLink 2.5
 */
public abstract class CommonAbstractCriteriaImpl<T> implements CommonAbstractCriteria, Serializable {

    private static final long serialVersionUID = -2729946665208116620L;

    protected Metamodel metamodel;
    protected Expression<Boolean> where;
    protected CriteriaBuilderImpl queryBuilder;
    protected Class queryType;

    protected Set<ParameterExpression<?>> parameters;

    public CommonAbstractCriteriaImpl(Metamodel metamodel, CriteriaBuilderImpl queryBuilder, Class<T> resultType){
        this.metamodel = metamodel;
        this.queryBuilder = queryBuilder;
        this.queryType = resultType;
    }

    /**
     * Return the predicate that corresponds to the where clause restriction(s).
     *
     * @return where clause predicate
     */
    @Override
    public Predicate getRestriction(){
        if (this.where == null) {
            return null;
        }
        if (((ExpressionImpl)this.where).isPredicate()) {
            return (Predicate)this.where;
        }
        return this.queryBuilder.isTrue(this.where);
    }

    /**
     * Return the result type of the query.
     * If a result type was specified as an argument to the
     * createQuery method, that type will be returned.
     * If the query was created using the createTupleQuery
     * method, the result type is Tuple.
     * Otherwise, the result type is Object.
     * @return result type
     */
    public Class<T> getResultType(){
        return this.queryType;
    }

    /**
     * Add a query root corresponding to the given entity, forming a Cartesian
     * product with any existing roots.
     *
     * @param entity
     *            metamodel entity representing the entity of type X
     * @return query root corresponding to the given entity
     */
    public Root internalFrom(EntityType entity) {
        RootImpl root = new RootImpl(entity, this.metamodel, entity.getBindableJavaType(), new ExpressionBuilder(entity.getBindableJavaType()), entity);
        integrateRoot(root);
        return root;
    }

    /**
     * Add a query root corresponding to the given entity, forming a Cartesian
     * product with any existing roots.
     *
     * @param entityClass
     *            the entity class
     * @return query root corresponding to the given entity
     */
    public Root internalFrom(Class entityClass) {
        EntityType entity = this.metamodel.entity(entityClass);
        return this.internalFrom(entity);
    }

    /**
     * Modify the query to restrict the query results according to the specified
     * boolean expression. Replaces the previously added restriction(s), if any.
     *
     * @param restriction
     *            a simple or compound boolean expression
     * @return the modified query
     */
    public CommonAbstractCriteria where(Expression<Boolean> restriction) {
        findRootAndParameters(restriction);
        this.where = restriction;
        return this;
    }

    /**
     * Modify the query to restrict the query results according to the
     * conjunction of the specified restriction predicates. Replaces the
     * previously added restriction(s), if any. If no restrictions are
     * specified, any previously added restrictions are simply removed.
     *
     * @param restrictions
     *            zero or more restriction predicates
     * @return the modified query
     */
    public CommonAbstractCriteria where(Predicate... restrictions) {
        if (restrictions == null || restrictions.length == 0){
            this.where = null;
        }
        Predicate predicate = this.queryBuilder.and(restrictions);
        findRootAndParameters(predicate);
        this.where = predicate;
        return this;
    }

    /**
     * Specify that the query is to be used as a subquery having the specified
     * return type.
     *
     * @return subquery corresponding to the query
     */
    @Override
    public <U> Subquery<U> subquery(Class<U> type) {
        return new SubQueryImpl<U>(metamodel, type, queryBuilder, this);
    }

    /**
     *  Used to use a root from a different query.
     */
    protected abstract void integrateRoot(RootImpl root);

    protected void findRootAndParameters(Expression<?> predicate) {
        ((InternalSelection) predicate).findRootAndParameters(this);
    }

    protected abstract org.eclipse.persistence.expressions.Expression getBaseExpression();

    public void addParameter(ParameterExpression<?> parameter) {
        if (this.parameters == null) {
            this.parameters = new HashSet<ParameterExpression<?>>();
        }
        this.parameters.add(parameter);
    }

    protected abstract DatabaseQuery getDatabaseQuery();

    /**
     * Return the parameters of the query
     *
     * @return the query parameters
     */
    public Set<ParameterExpression<?>> getParameters() {
        if (this.parameters == null) {
            this.parameters = new HashSet<ParameterExpression<?>>();
        }
        return this.parameters;
    }


    /**
     * Translates from the criteria query to a EclipseLink Database Query.
     */
    public DatabaseQuery translate() {
        DatabaseQuery query = getDatabaseQuery();
        for (ParameterExpression<?> parameter : getParameters()) {
            query.addArgument(((ParameterExpressionImpl)parameter).getInternalName(), parameter.getJavaType());
        }
        if (this.where != null) {
            if (((InternalExpression) this.where).isJunction()) {
                if (!((PredicateImpl) this.where).getJunctionValue()) {
                    query.setSelectionCriteria(new ConstantExpression(1, getBaseExpression()).equal(0));
                }
            } else {
                query.setSelectionCriteria(((InternalSelection) this.where).getCurrentNode());
            }
        }

        return query;
    }

}
