/*
 * Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2019 IBM 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
//
package org.eclipse.persistence.internal.jpa.jpql;

import java.util.Collection;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.history.AsOfSCNClause;
import org.eclipse.persistence.jpa.jpql.LiteralType;
import org.eclipse.persistence.jpa.jpql.parser.AbstractEclipseLinkExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AbstractFromClause;
import org.eclipse.persistence.jpa.jpql.parser.AbstractSelectClause;
import org.eclipse.persistence.jpa.jpql.parser.AbstractSelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.AsOfClause;
import org.eclipse.persistence.jpa.jpql.parser.AvgFunction;
import org.eclipse.persistence.jpa.jpql.parser.CollectionExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionMemberDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.ConstructorExpression;
import org.eclipse.persistence.jpa.jpql.parser.CountFunction;
import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkAnonymousExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.FromClause;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariableDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.Join;
import org.eclipse.persistence.jpa.jpql.parser.KeyExpression;
import org.eclipse.persistence.jpa.jpql.parser.MaxFunction;
import org.eclipse.persistence.jpa.jpql.parser.MinFunction;
import org.eclipse.persistence.jpa.jpql.parser.ObjectExpression;
import org.eclipse.persistence.jpa.jpql.parser.OrderByClause;
import org.eclipse.persistence.jpa.jpql.parser.OrderByItem;
import org.eclipse.persistence.jpa.jpql.parser.RangeVariableDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.ResultVariable;
import org.eclipse.persistence.jpa.jpql.parser.SelectClause;
import org.eclipse.persistence.jpa.jpql.parser.SelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.SimpleFromClause;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectClause;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.StateFieldPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.SumFunction;
import org.eclipse.persistence.jpa.jpql.parser.UnionClause;
import org.eclipse.persistence.jpa.jpql.parser.ValueExpression;
import org.eclipse.persistence.jpa.jpql.parser.WhereClause;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReportQuery;

/**
 * This visitor is responsible to populate an {@link ObjectLevelReadQuery} by traversing a {@link
 * org.eclipse.persistence.jpa.jpql.parser.Expression JPQL Expression} representing a
 * <b>SELECT</b> query.
 *
 * @see ObjectLevelReadQueryVisitor
 * @see ReportQueryVisitor
 *
 * @version 2.5
 * @since 2.3
 * @author Pascal Filion
 * @author John Bracken
 */
abstract class AbstractObjectLevelReadQueryVisitor extends AbstractEclipseLinkExpressionVisitor {

    /**
     * The {@link ObjectLevelReadQuery} to populate.
     */
    ObjectLevelReadQuery query;

    /**
     * The {@link JPQLQueryContext} is used to query information about the application metadata and
     * cached information.
     */
    final JPQLQueryContext queryContext;

    /**
     * Creates a new <code>ReadAllQueryVisitor</code>.
     *
     * @param queryContext The context used to query information about the application metadata and
     * cached information
     * @param query The {@link ObjectLevelReadQuery} to populate by using this visitor to visit the
     * parsed tree representation of the JPQL query
     */
    AbstractObjectLevelReadQueryVisitor(JPQLQueryContext queryContext, ObjectLevelReadQuery query) {
        super();
        this.query = query;
        this.queryContext = queryContext;
    }

    @Override
    public void visit(AsOfClause expression) {

        Expression queryExpression = queryContext.buildExpression(expression);
        org.eclipse.persistence.history.AsOfClause asOfClause;

        if (expression.hasScn()) {
            asOfClause = new AsOfSCNClause(queryExpression);
        }
        else {
            asOfClause = new org.eclipse.persistence.history.AsOfClause(queryExpression);
        }

        query.setAsOfClause(asOfClause);
        query.setShouldMaintainCache(false);
    }

    @Override
    public void visit(CollectionExpression expression) {
        expression.acceptChildren(this);
    }

    @Override
    public void visit(FromClause expression) {
        visitAbstractFromClause(expression);
    }

    @Override
    public void visit(IdentificationVariable expression) {
        visitIdentificationVariable(expression);
    }

    @Override
    public void visit(ObjectExpression expression) {
        expression.getExpression().accept(this);
    }

    @Override
    public void visit(OrderByClause expression) {
        expression.getOrderByItems().accept(this);
    }

    @Override
    public void visit(OrderByItem expression) {
        Expression queryExpression = queryContext.buildExpression(expression);
        query.addOrdering(queryExpression);
    }

    @Override
    public void visit(SelectClause expression) {
        // Select couple flags
        visitAbstractSelectClause(expression);
    }

    @Override
    public void visit(SelectStatement expression) {

        // Handle SELECT/FROM/WHERE clauses
        visitAbstractSelectStatement(expression);

        // ORDER BY clause
        if (expression.hasOrderByClause()) {
            expression.getOrderByClause().accept(this);
        }

        // UNION clauses
        if (expression.hasUnionClauses()) {
            expression.getUnionClauses().accept(this);
        }
    }

    @Override
    public void visit(SimpleFromClause expression) {
        visitAbstractFromClause(expression);
    }

    @Override
    public void visit(SimpleSelectClause expression) {
        // Select couple flags
        visitAbstractSelectClause(expression);
    }

    @Override
    public void visit(SimpleSelectStatement expression) {
        // Handle SELECT/FROM/WHERE
        visitAbstractSelectStatement(expression);
    }

    @Override
    public void visit(UnionClause expression) {

        ReportQuery subquery = queryContext.buildSubquery((SimpleSelectStatement) expression.getQuery());
        Expression union = null;

        if (expression.isUnion()) {
            if (expression.hasAll()) {
                union = query.getExpressionBuilder().unionAll(subquery);
            }
            else {
                union = query.getExpressionBuilder().union(subquery);
            }
        }
        else if (expression.isIntersect()) {
            if (expression.hasAll()) {
                union = query.getExpressionBuilder().intersectAll(subquery);
            }
            else {
                union = query.getExpressionBuilder().intersect(subquery);
            }
        }
        else if (expression.isExcept()) {
            if (expression.hasAll()) {
                union = query.getExpressionBuilder().exceptAll(subquery);
            }
            else {
                union = query.getExpressionBuilder().except(subquery);
            }
        }

        query.addUnionExpression(union);
    }

    @Override
    public void visit(WhereClause expression) {
        query.setSelectionCriteria(queryContext.buildExpression(expression));
    }

    void visitAbstractFromClause(AbstractFromClause expression) {

        // Set the ExpressionBuilder
        Expression baseExpression = queryContext.getBaseExpression();
        ExpressionBuilder expressionBuilder = baseExpression.getBuilder();
        query.setExpressionBuilder(expressionBuilder);

        // Set the reference class if it's not set
        if (query.getReferenceClass() == null) {
            query.setReferenceClass(expressionBuilder.getQueryClass());
            query.changeDescriptor(queryContext.getSession());
        }

        // Add join expressions to the query (but not the join fetch expressions)
        JoinVisitor visitor = new JoinVisitor();
        expression.accept(visitor);

        // Visit the AS OF clause
        if (expression.hasAsOfClause()) {
            expression.getAsOfClause().accept(this);
        }

        // Visit the hierarchical clause
        if (expression.hasHierarchicalQueryClause()) {
            expression.getHierarchicalQueryClause().accept(this);
        }
    }

    void visitAbstractSelectClause(AbstractSelectClause expression) {

        // DISTINCT
        if (expression.hasDistinct()) {

            CountFunctionVisitor visitor = new CountFunctionVisitor();
            expression.accept(visitor);

            if (!visitor.hasCountFunction) {
                query.useDistinct();
            }
        }

        // Indicate on the query if "return null if primary key null".
        // This means we want nulls returned if we expect an outer join
        // True:  SELECT employee.address FROM ..... // Simple 1:1
        // True:  SELECT a.b.c.d FROM ..... // where a->b, b->c and c->d are all 1:1.
        // False: SELECT OBJECT(employee) FROM ..... // simple SELECT
        // False: SELECT phoneNumber.areaCode FROM ..... // direct-to-field
        OneToOneSelectedVisitor visitor = new OneToOneSelectedVisitor();
        expression.accept(visitor);
        query.setShouldBuildNullForNullPk(visitor.oneToOneSelected);

        // Now visit the select expression
        expression.getSelectExpression().accept(this);
    }

    void visitAbstractSelectStatement(AbstractSelectStatement expression) {

        // First visit the FROM clause in order to retrieve the reference classes and
        // create an ExpressionBuilder for each abstract schema name
        expression.getFromClause().accept(this);
        expression.getSelectClause().accept(this);

        if (expression.hasWhereClause()) {
            expression.getWhereClause().accept(this);
        }
    }

    void visitIdentificationVariable(IdentificationVariable expression) {

        String variableName = expression.getVariableName();

        // Retrieve the join fetches that were defined in the same identification variable
        // declaration, if the identification variable is mapped to a join, then there will
        // not be any join fetch associated with it
        Collection<Join> joinFetches = queryContext.getJoinFetches(variableName);

        if (joinFetches != null ) {

            for (Join joinFetch : joinFetches) {


                // Retrieve the join association path expression's identification variable
                String joinFetchVariableName = queryContext.literal(
                    joinFetch,
                    LiteralType.PATH_EXPRESSION_IDENTIFICATION_VARIABLE
                );

                // Both identification variables are the same.
                // Then add the join associated path expression as a joined attribute
                // Example: FROM Employee e JOIN FETCH e.employees
                if (variableName.equals(joinFetchVariableName)) {
                    org.eclipse.persistence.expressions.Expression queryExpression = null;
                    if (joinFetch.hasIdentificationVariable()){
                        String identificationVariable = queryContext.literal(joinFetch, LiteralType.IDENTIFICATION_VARIABLE);
                        queryExpression =queryContext.findQueryExpression(identificationVariable);
                            //Join expression has identification variable and was processed in the From clause
                    }
                    if (queryExpression == null){
                        queryExpression = queryContext.buildExpression(joinFetch);
                    }
                    query.addJoinedAttribute(queryExpression);
                }
            }
        }
    }

    private static class CountFunctionVisitor extends EclipseLinkAnonymousExpressionVisitor {

        /**
         * Determines whether the single {@link org.eclipse.persistence.jpa.jpql.parser.Expression
         * Expression} is the <b>COUNT</b> expression.
         */
        boolean hasCountFunction;

        @Override
        public void visit(CountFunction expression) {
            hasCountFunction = true;
        }

        @Override
        protected void visit(org.eclipse.persistence.jpa.jpql.parser.Expression expression) {
            hasCountFunction = false;
        }

        @Override
        public void visit(SelectClause expression) {
            expression.getSelectExpression().accept(this);
        }

        @Override
        public void visit(SimpleSelectClause expression) {
            expression.getSelectExpression().accept(this);
        }
    }

    private class JoinVisitor extends AbstractEclipseLinkExpressionVisitor {

        /**
         * Cache the Expression associated with the identification variable so it can be used in the
         * visit(Join) in order to properly create the ON clause expression.
         */
        private Expression baseExpression;

        private Expression addNonFetchJoinedAttribute(org.eclipse.persistence.jpa.jpql.parser.Expression expression,
                                                      IdentificationVariable identificationVariable) {

            String variableName = identificationVariable.getVariableName();

            // Always add the expression, as it may not be defined elsewhere,
            // unless it has already been defined as the builder.
            Expression queryExpression = queryContext.getQueryExpression(variableName);

            if (queryExpression == null) {
                queryExpression = queryContext.buildExpression(expression);
                queryContext.addQueryExpression(variableName, queryExpression);
            }

            ObjectLevelReadQuery query = queryContext.getDatabaseQuery();

            if (query.getExpressionBuilder() != queryExpression) {
                query.addNonFetchJoinedAttribute(queryExpression);
            }

            return queryExpression;
        }

        @Override
        public void visit(CollectionExpression expression) {
            expression.acceptChildren(this);
        }

        @Override
        public void visit(CollectionMemberDeclaration expression) {
            addNonFetchJoinedAttribute(
                expression,
                (IdentificationVariable) expression.getIdentificationVariable()
            );
        }

        @Override
        public void visit(FromClause expression) {
            expression.getDeclaration().accept(this);
        }

        @Override
        public void visit(IdentificationVariableDeclaration expression) {

            expression.getRangeVariableDeclaration().accept(this);

            if (expression.hasJoins()) {
                expression.getJoins().accept(this);
            }
        }

        @Override
        public void visit(Join expression) {

            if (expression.hasIdentificationVariable()) {

                IdentificationVariable identificationVariable = (IdentificationVariable) expression.getIdentificationVariable();
                Expression queryExpression = null;

                if (expression.hasFetch()){
                    String variableName = identificationVariable.getVariableName();
                    queryExpression = queryContext.getQueryExpression(variableName);

                    if (queryExpression == null) {
                        queryExpression = queryContext.buildExpression(expression);
                        queryContext.addQueryExpression(variableName, queryExpression);
                    }
                } else {
                    queryExpression = addNonFetchJoinedAttribute(expression, identificationVariable);
                }

                // Add the ON clause to the expression
                if (expression.hasOnClause()) {
                    Expression onClause = queryContext.buildExpression(expression.getOnClause());

                    // Create the JOIN expression using the base Expression
                    //'queryExpression' will be altered pass-by-reference
                    if (expression.isLeftJoin()) {
                        baseExpression.leftJoin(queryExpression, onClause);
                    } else {
                        baseExpression.join(queryExpression, onClause);
                    }
                }
            }
        }

        @Override
        public void visit(RangeVariableDeclaration expression) {
            baseExpression = addNonFetchJoinedAttribute(
                expression,
                (IdentificationVariable) expression.getIdentificationVariable()
            );
        }

        @Override
        public void visit(SimpleFromClause expression) {
            expression.getDeclaration().accept(this);
        }
    }

    private class OneToOneSelectedVisitor extends EclipseLinkAnonymousExpressionVisitor {

        /**
         * Determines whether the visited {@link org.eclipse.persistence.jpa.jpql.parser.Expression
         * Expression} represents a relationship.
         */
        boolean oneToOneSelected;

        @Override
        public void visit(AvgFunction expression) {
            expression.getExpression().accept(this);
        }

        @Override
        public void visit(CollectionExpression expression) {
            for (org.eclipse.persistence.jpa.jpql.parser.Expression child : expression.children()) {
                child.accept(this);
                if (oneToOneSelected) {
                    break;
                }
            }
        }

        @Override
        public void visit(ConstructorExpression expression) {
            expression.getConstructorItems().accept(this);
        }

        @Override
        public void visit(CountFunction expression) {
            oneToOneSelected = false;
        }

        @Override
        public void visit(IdentificationVariable expression) {
            oneToOneSelected = !queryContext.isRangeIdentificationVariable(expression.getVariableName());
        }

        @Override
        public void visit(KeyExpression expression) {
            oneToOneSelected = true;
        }

        @Override
        public void visit(MaxFunction expression) {
            expression.getExpression().accept(this);
        }

        @Override
        public void visit(MinFunction expression) {
            expression.getExpression().accept(this);
        }

        @Override
        public void visit(ObjectExpression expression) {
            expression.getExpression().accept(this);
        }

        @Override
        protected void visit(org.eclipse.persistence.jpa.jpql.parser.Expression expression) {
            oneToOneSelected = true;
        }

        @Override
        public void visit(ResultVariable expression) {
            expression.getSelectExpression().accept(this);
        }

        @Override
        public void visit(SelectClause expression) {
            expression.getSelectExpression().accept(this);
        }

        @Override
        public void visit(SimpleSelectClause expression) {
            expression.getSelectExpression().accept(this);
        }

        @Override
        public void visit(StateFieldPathExpression expression) {
            DatabaseMapping mapping = queryContext.resolveMapping(expression);
            oneToOneSelected = (mapping != null) && !mapping.isDirectToFieldMapping();
        }

        @Override
        public void visit(SumFunction expression) {
            expression.getExpression().accept(this);
        }

        @Override
        public void visit(ValueExpression expression) {
            oneToOneSelected = true;
        }
    }
}
