/*
 * Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2011, 2021 IBM Corporation. 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:
//     Gordon Yorke - Initial development
//     02/03/2017 - Dalia Abo Sheasha
//       - 509693 : EclipseLink generates inconsistent SQL statements for SubQuery
package org.eclipse.persistence.internal.jpa.querydef;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import jakarta.persistence.criteria.AbstractQuery;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import jakarta.persistence.metamodel.EntityType;
import jakarta.persistence.metamodel.Metamodel;

import org.eclipse.persistence.expressions.ExpressionBuilder;

/**
 * <p>
 * <b>Purpose</b>: Contains the implementation of the AbstractQuery 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 both the CriteriaQuery and the
 * SubQuery.
 * <p>
 *
 * @see jakarta.persistence.criteria CriteriaQuery
 *
 * @author gyorke
 * @since EclipseLink 1.2
 */
public abstract class AbstractQueryImpl<T> extends CommonAbstractCriteriaImpl<T> implements AbstractQuery<T> {

    private static final long serialVersionUID = -5270020290752637882L;

    protected ResultType queryResult;
    protected boolean distinct;
    protected Predicate havingClause;
    protected List<Expression<?>> groupBy;
    protected Set<Root<?>> roots;
    protected org.eclipse.persistence.expressions.Expression baseExpression;

    protected enum ResultType{
        UNKNOWN, OBJECT_ARRAY, PARTIAL, TUPLE, ENTITY, CONSTRUCTOR, OTHER
    }

    public AbstractQueryImpl(Metamodel metamodel, ResultType queryResult, CriteriaBuilderImpl queryBuilder, Class<T> resultType){
        super(metamodel, queryBuilder, resultType);
        this.roots = new HashSet<Root<?>>();
        this.queryResult = queryResult;
        this.baseExpression = new ExpressionBuilder();
    }

    /**
     * Specify the expressions that are used to form groups over
     * the query results.
     * Replaces the previous specified grouping expressions, if any.
     * If no grouping expressions are specified, any previously
     * added grouping expressions are simply removed.
     * @param grouping  list of zero or more grouping expressions
     * @return the modified query
     */
    @Override
    public AbstractQuery<T> groupBy(List<Expression<?>> grouping){
        this.groupBy = grouping;
        return this;
    }


    /**
     * Specify the expressions that are used to form groups over the query
     * results. Replaces the previous specified grouping expressions, if any. If
     * no grouping expressions are specified, any previously added grouping
     * expressions are simply removed.
     *
     * @param grouping
     *            zero or more grouping expressions
     * @return the modified query
     */
    @Override
    public AbstractQuery<T> groupBy(Expression<?>... grouping){
        this.groupBy = new ArrayList<Expression<?>>();
        for (Expression<?> exp : grouping){
            this.groupBy.add(exp);
        }
        return this;
    }

    /**
     * Specify a restriction over the groups of the query. Replaces the previous
     * having restriction(s), if any.
     *
     * @param restriction
     *            a simple or compound boolean expression
     * @return the modified query
     */
    @Override
    public AbstractQuery<T> having(Expression<Boolean> restriction) {
        findRootAndParameters(restriction);
        if (((InternalExpression)restriction).isCompoundExpression() || ((InternalExpression)restriction).isPredicate()) {
            this.havingClause = (Predicate) restriction;
        } else {
            this.havingClause = queryBuilder.isTrue(restriction);
        }
        return this;
    }

    /**
     * Specify restrictions over the groups of the query according 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
     */
    @Override
    public AbstractQuery<T> having(Predicate... restrictions){
        if (restrictions != null && restrictions.length > 0) {
            Predicate conjunction = this.queryBuilder.conjunction();
            for (Predicate predicate : restrictions) {
                conjunction = this.queryBuilder.and(conjunction, predicate);
            }
            findRootAndParameters(conjunction);
            this.havingClause = conjunction;
        }
        return this;
    }

    public abstract void addJoin(FromImpl join);

    /**
     * Specify whether duplicate query results will be eliminated. A true value
     * will cause duplicates to be eliminated. A false value will cause
     * duplicates to be retained. If distinct has not been specified, duplicate
     * results must be retained. This method only overrides the return type of
     * the corresponding AbstractQuery method.
     *
     * @param distinct
     *            boolean value specifying whether duplicate results must be
     *            eliminated from the query result or whether they must be
     *            retained
     * @return the modified query.
     */
    @Override
    public AbstractQuery<T> distinct(boolean distinct){
        this.distinct= distinct;
        return this;
    }

    @Override
    protected org.eclipse.persistence.expressions.Expression getBaseExpression() {
        return getBaseExpression(null);
    }
    
    protected org.eclipse.persistence.expressions.Expression getBaseExpression(Root root) {
        if (this.roots.isEmpty()) {
            baseExpression = new ExpressionBuilder();
        } else if (this.roots.size() == 1) {
            baseExpression = ((RootImpl) this.roots.iterator().next()).getCurrentNode();
        } else if (root != null) {
            for (Root r : this.roots) {
                if (r == root) {
                    baseExpression = ((RootImpl) r).getCurrentNode();
                }
            }
        }
        return baseExpression;
    }

    /**
     * Return a list of the grouping expressions
     * @return the list of grouping expressions
     */
    @Override
    public List<Expression<?>> getGroupList(){
        if (this.groupBy == null){
            this.groupBy = new ArrayList<Expression<?>>();
        }
        return this.groupBy;
    }

    /**
     * Return the predicate that corresponds to the restriction(s) over the
     * grouping items.
     *
     * @return having clause predicate
     */
    @Override
    public Predicate getGroupRestriction(){
        return this.havingClause;
    }

    /**
     * Return the query roots.
     *
     * @return the set of query roots
     */
    @Override
    public Set<Root<?>> getRoots(){
        return this.roots;
    }

    @Override
    protected void integrateRoot(RootImpl root) {
        if (!this.roots.contains(root)) {
            this.roots.add(root);
        }
    }

    /**
     * Return whether duplicate query results must be eliminated or retained.
     *
     * @return boolean indicating whether duplicate query results must be
     *         eliminated
     */
    @Override
    public boolean isDistinct(){
        return this.distinct;
    }

    protected void findJoins(FromImpl root) {
        root.findJoins(this);
    }

    /**
     * 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
     */
    @Override
    public <X> Root<X> from(EntityType<X> entity) {
        return this.internalFrom(entity);
    }

    /**
     * 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
     */
    @Override
    public <X> Root<X> from(Class<X> entityClass) {
        return this.internalFrom(entityClass);
    }

    // override the return type only:
    /**
     * Modify the query to restrict the query result according to the specified
     * boolean expression. Replaces the previously added restriction(s), if any.
     * This method only overrides the return type of the corresponding
     * AbstractQuery method.
     *
     * @param restriction
     *            a simple or compound boolean expression
     * @return the modified query
     */
    @Override
    public AbstractQuery<T> where(Expression<Boolean> restriction){
        return (AbstractQuery<T>)super.where(restriction);
    }

    /**
     * Modify the query to restrict the query result 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. This
     * method only overrides the return type of the corresponding AbstractQuery
     * method.
     *
     * @param restrictions
     *            zero or more restriction predicates
     * @return the modified query
     */
    @Override
    public AbstractQuery<T> where(Predicate... restrictions) {
        return (AbstractQuery<T>) super.where(restrictions);
    }

}
