/*
 * Copyright (c) 2006, 2019 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;
    }

    /**
     * {@inheritDoc}
     */
    @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);
    }

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

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

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

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

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

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

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

    /**
     * {@inheritDoc}
     */
    @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);
        }
    }

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

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

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

    /**
     * {@inheritDoc}
     */
    @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);
    }

    /**
     * {@inheritDoc}
     */
    @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;

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

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

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

        /**
         * {@inheritDoc}
         */
        @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;
        }

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

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

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

        /**
         * {@inheritDoc}
         */
        @Override
        public void visit(IdentificationVariableDeclaration expression) {

            expression.getRangeVariableDeclaration().accept(this);

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

        /**
         * {@inheritDoc}
         */
        @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);
                    }
                }
            }
        }

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

        /**
         * {@inheritDoc}
         */
        @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;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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