/*
 * 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:
//     Oracle - initial API and implementation
//
package org.eclipse.persistence.internal.jpa.jpql;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.JPQLQueryDeclaration.Type;
import org.eclipse.persistence.jpa.jpql.LiteralType;
import org.eclipse.persistence.jpa.jpql.parser.AbstractEclipseLinkExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AbstractSchemaName;
import org.eclipse.persistence.jpa.jpql.parser.CollectionExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionMemberDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.CollectionValuedPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.DeleteClause;
import org.eclipse.persistence.jpa.jpql.parser.DeleteStatement;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
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.JPQLExpression;
import org.eclipse.persistence.jpa.jpql.parser.Join;
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.SubExpression;
import org.eclipse.persistence.jpa.jpql.parser.TableVariableDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.UpdateClause;
import org.eclipse.persistence.jpa.jpql.parser.UpdateStatement;

/**
 * This visitor visits the declaration clause of the JPQL query and creates the list of
 * {@link Declaration Declarations}.
 *
 * @version 2.5
 * @since 2.4
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
final class DeclarationResolver {

    /**
     * The first {@link Declaration} that was created when visiting the declaration clause.
     */
    private Declaration baseDeclaration;

    /**
     * The {@link Declaration} objects mapped to their identification variable.
     */
    private List<Declaration> declarations;

    /**
     * The parent {@link DeclarationResolver} which represents the superquery's declaration or
     * <code>null</code> if this is used for the top-level query.
     */
    private DeclarationResolver parent;

    /**
     * Determines whether the {@link Declaration Declaration} objects were created after visiting the
     * query's declaration clause.
     */
    private boolean populated;

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

    /**
     * The result variables used to identify select expressions.
     */
    private Collection<IdentificationVariable> resultVariables;

    /**
     * Creates a new <code>DeclarationResolver</code>.
     *
     * @param queryContext The context used to query information about the application metadata and
     * cached information
     * @param parent The parent {@link DeclarationResolver} which represents the superquery's declaration
     */
    DeclarationResolver(JPQLQueryContext queryContext, DeclarationResolver parent) {
        super();
        initialize(queryContext, parent);
    }

    /**
     * Adds a "virtual" range variable declaration that will be used when parsing a JPQL fragment.
     *
     * @param entityName The name of the entity to be accessible with the given variable name
     * @param variableName The identification variable used to navigate to the entity
     */
    void addRangeVariableDeclaration(String entityName, String variableName) {

        // This method should only be used by HermesParser.buildSelectionCriteria(),
        // initializes these variables right away since this method should only be
        // called by HermesParser.buildSelectionCriteria()
        populated = true;
        resultVariables = Collections.emptySet();

        // Create the "virtual" range variable declaration
        RangeVariableDeclaration rangeVariableDeclaration = new RangeVariableDeclaration(
            entityName,
            variableName
        );

        // Make sure the identification variable was not declared more than once,
        // this could cause issues when trying to resolve it
        RangeDeclaration declaration = new RangeDeclaration(queryContext);
        declaration.rootPath               = entityName;
        declaration.baseExpression         = rangeVariableDeclaration;
        declaration.identificationVariable = (IdentificationVariable) rangeVariableDeclaration.getIdentificationVariable();

        declarations.add(declaration);

        // Make sure it is marked as the base declaration and the base Expression is created
        if (baseDeclaration == null) {
            baseDeclaration = declaration;

            // Make sure the base Expression is initialized, which will cache it
            // into the right context as well (the top-level context)
            declaration.getQueryExpression();
        }
    }

    /**
     * Converts the given {@link Declaration} from being set as a range variable declaration to
     * a path expression declaration.
     * <p>
     * In this query "{@code UPDATE Employee SET firstName = 'MODIFIED' WHERE (SELECT COUNT(m) FROM
     * managedEmployees m) > 0}" <em>managedEmployees</em> is an unqualified collection-valued
     * path expression (<code>employee.managedEmployees</code>).
     *
     * @param declaration The {@link Declaration} that was parsed to range over an abstract schema
     * name but is actually ranging over a path expression
     * @param outerVariableName The identification variable coming from the parent identification
     * variable declaration
     */
    void convertUnqualifiedDeclaration(RangeDeclaration declaration, String outerVariableName) {

        QualifyRangeDeclarationVisitor visitor = new QualifyRangeDeclarationVisitor();

        // Convert the declaration expression into a derived declaration
        visitor.declaration       = declaration;
        visitor.outerVariableName = outerVariableName;
        visitor.queryContext      = queryContext.getCurrentContext();

        declaration.declarationExpression.accept(visitor);

        // Now replace the old declaration with the new one
        int index = declarations.indexOf(declaration);
        declarations.set(index, visitor.declaration);

        // Update the base declaration
        if (baseDeclaration == declaration) {
            baseDeclaration = visitor.declaration;
        }
    }

    /**
     * Retrieves the {@link Declaration} for which the given variable name is used to navigate to the
     * "root" object.
     *
     * @param variableName The name of the identification variable that is used to navigate a "root"
     * object
     * @return The {@link Declaration} containing the information about the identification variable
     * declaration
     */
    Declaration getDeclaration(String variableName) {

        for (Declaration declaration : declarations) {
            if (declaration.getVariableName().equalsIgnoreCase(variableName)) {
                return declaration;
            }
        }

        return null;
    }

    /**
     * Returns the ordered list of {@link Declaration Declarations}.
     *
     * @return The {@link Declaration Declarations} of the current query that was parsed
     */
    List<Declaration> getDeclarations() {
        return declarations;
    }

    /**
     * Returns the first {@link Declaration} that was created after visiting the declaration clause.
     *
     * @return The first {@link Declaration} object
     */
    Declaration getFirstDeclaration() {
        return baseDeclaration;
    }

    /**
     * Returns the parsed representation of a <b>JOIN FETCH</b> that were defined in the same
     * declaration than the given range identification variable name.
     *
     * @param variableName The name of the identification variable that should be used to define an entity
     * @return The <b>JOIN FETCH</b> expressions used in the same declaration or an empty collection
     * if none was defined
     */
    Collection<Join> getJoinFetches(String variableName) {

        Declaration declaration = getDeclaration(variableName);

        if ((declaration != null) && (declaration.getType() == Type.RANGE)) {
            RangeDeclaration rangeDeclaration = (RangeDeclaration) declaration;
            if (rangeDeclaration.hasJoins()) {
                return rangeDeclaration.getJoinFetches();
            }
        }

        return null;
    }

    /**
     * Returns the parent of this {@link DeclarationResolver}.
     *
     * @return The parent of this {@link DeclarationResolver} if this is used for a subquery or
     * <code>null</code> if this is used for the top-level query
     */
    DeclarationResolver getParent() {
        return parent;
    }

    /**
     * Returns the variables that got defined in the select expression. This only applies to JPQL
     * queries built for JPA 2.0 or later.
     *
     * @return The variables identifying the select expressions, if any was defined or an empty set
     * if none were defined
     */
    Collection<IdentificationVariable> getResultVariables() {

        if (parent != null) {
            return parent.getResultVariables();
        }

        if (resultVariables == null) {
            ResultVariableVisitor visitor = new ResultVariableVisitor();
            queryContext.getJPQLExpression().accept(visitor);
            resultVariables = visitor.resultVariables;
        }

        return resultVariables;
    }

    /**
     * Initializes this <code>DeclarationResolver</code>.
     *
     * @param queryContext The context used to query information about the query
     * @param parent The parent {@link DeclarationResolver}, which is not <code>null</code> when this
     * resolver is created for a subquery
     */
    private void initialize(JPQLQueryContext queryContext, DeclarationResolver parent) {
        this.parent       = parent;
        this.queryContext = queryContext;
        this.declarations = new LinkedList<>();
    }

    /**
     * Determines whether the given identification variable is defining a <b>JOIN</b> expression or
     * in a <code>IN</code> expressions for a collection-valued field. If the search didn't find the
     * identification in this resolver, then it will traverse the parent hierarchy.
     *
     * @param variableName The identification variable to check for what it maps
     * @return <code>true</code> if the given identification variable maps a collection-valued field
     * defined in a <code>JOIN</code> or <code>IN</code> expression; <code>false</code> otherwise
     */
    boolean isCollectionIdentificationVariable(String variableName) {

        boolean result = isCollectionIdentificationVariableImp(variableName);

        if (!result && (parent != null)) {
            result = parent.isCollectionIdentificationVariableImp(variableName);
        }

        return result;
    }

    /**
     * Determines whether the given identification variable is defining a <b>JOIN</b> expression or
     * in a <code>IN</code> expressions for a collection-valued field. The search does not traverse
     * the parent hierarchy.
     *
     * @param variableName The identification variable to check for what it maps
     * @return <code>true</code> if the given identification variable maps a collection-valued field
     * defined in a <code>JOIN</code> or <code>IN</code> expression; <code>false</code> otherwise
     */
    @SuppressWarnings({"fallthrough"})
    boolean isCollectionIdentificationVariableImp(String variableName) {

        for (Declaration declaration : declarations) {

            switch (declaration.getType()) {

                case COLLECTION: {
                    if (declaration.getVariableName().equalsIgnoreCase(variableName)) {
                        return true;
                    }
                    return false;
                }

                case RANGE:
                case DERIVED: {

                    AbstractRangeDeclaration rangeDeclaration = (AbstractRangeDeclaration) declaration;

                    // Check the JOIN expressions
                    for (Join join : rangeDeclaration.getJoins()) {

                        String joinVariableName = queryContext.literal(
                            join.getIdentificationVariable(),
                            LiteralType.IDENTIFICATION_VARIABLE
                        );

                        if (joinVariableName.equalsIgnoreCase(variableName)) {
                            // Make sure the JOIN expression maps a collection mapping
                            Declaration joinDeclaration = queryContext.getDeclaration(joinVariableName);
                            return joinDeclaration.getMapping().isCollectionMapping();
                        }
                    }
                }
                default:
                    continue;
            }
        }

        return false;
    }

    /**
     * Determines whether the given variable name is an identification variable name used to define
     * an abstract schema name.
     *
     * @param variableName The name of the variable to verify if it's defined in a range variable
     * declaration in the current query or any parent query
     * @return <code>true</code> if the variable name is mapping an abstract schema name; <code>false</code>
     * if it's defined in a collection member declaration
     */
    boolean isRangeIdentificationVariable(String variableName) {
        boolean result = isRangeIdentificationVariableImp(variableName);
        if (!result && (parent != null)) {
            result = parent.isRangeIdentificationVariableImp(variableName);
        }
        return result;
    }

    private boolean isRangeIdentificationVariableImp(String variableName) {
        Declaration declaration = getDeclaration(variableName);
        return (declaration != null) && declaration.getType().isRange();
    }

    /**
     * Determines whether the given variable is a result variable or not.
     *
     * @param variableName The variable to check if it used to identify a select expression
     * @return <code>true</code> if the given variable is defined as a result variable;
     * <code>false</code> otherwise
     */
    boolean isResultVariable(String variableName) {

        // Only the top-level SELECT query has result variables
        if (parent != null) {
            return parent.isResultVariable(variableName);
        }

        for (IdentificationVariable resultVariable : getResultVariables()) {
            if (resultVariable.getText().equalsIgnoreCase(variableName)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Visits the given {@link Expression} (which is either the top-level query or a subquery) and
     * retrieve the information from its declaration clause.
     *
     * @param expression The {@link Expression} to visit in order to retrieve the information
     * contained in the given query's declaration
     */
    void populate(Expression expression) {
        if (!populated) {
            populated = true;
            populateImp(expression);
        }
    }

    private void populateImp(Expression expression) {

        DeclarationVisitor visitor = new DeclarationVisitor();
        visitor.queryContext = queryContext;
        visitor.declarations = declarations;

        expression.accept(visitor);
        baseDeclaration = visitor.baseDeclaration;
    }

    private static class DeclarationVisitor extends AbstractEclipseLinkExpressionVisitor {

        /**
         * The first {@link Declaration} that was created when visiting the declaration clause.
         */
        private Declaration baseDeclaration;

        /**
         * This flag is used to determine what to do in {@link #visit(SimpleSelectStatement)}.
         */
        private boolean buildingDeclaration;

        /**
         * The {@link Declaration} being populated.
         */
        private Declaration currentDeclaration;

        /**
         * The list of {@link Declaration} objects to which new ones will be added by traversing the
         * declaration clause.
         */
        List<Declaration> declarations;

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

        @Override
        public void visit(AbstractSchemaName expression) {

            String rootPath = expression.getText();

            // Abstract schema name (entity name)
            if (rootPath.indexOf('.') == -1) {
                currentDeclaration = new RangeDeclaration(queryContext);
            }
            else {

                // Check to see if the "root" path is a class name before assuming it's a derived path
                Class<?> type = queryContext.getType(rootPath);

                // Fully qualified class name
                if (type != null) {
                    RangeDeclaration declaration = new RangeDeclaration(queryContext);
                    declaration.type = type;
                    currentDeclaration = declaration;
                }
                // Derived path expression (for subqueries)
                else {
                    currentDeclaration = new DerivedDeclaration(queryContext);
                }
            }

            currentDeclaration.rootPath = rootPath;
        }

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

        @Override
        public void visit(CollectionMemberDeclaration expression) {

            Declaration declaration = new CollectionDeclaration(queryContext);
            declaration.baseExpression        = expression.getCollectionValuedPathExpression();
            declaration.rootPath              = declaration.baseExpression.toActualText();
            declaration.declarationExpression = expression;
            declarations.add(declaration);

            // A derived collection member declaration does not have an identification variable
            if (!expression.isDerived()) {
                IdentificationVariable identificationVariable = (IdentificationVariable) expression.getIdentificationVariable();
                declaration.identificationVariable = identificationVariable;
            }

            // This collection member declaration is the first defined,
            // it is then the base Declaration
            if (baseDeclaration == null) {
                baseDeclaration = declaration;
            }
        }

        @Override
        public void visit(CollectionValuedPathExpression expression) {

            String rootPath = expression.toParsedText();

            // Check to see if the "root" path is a class name before assuming it's a derived path
            Class<?> type = queryContext.getType(rootPath);

            // Fully qualified class name
            if (type != null) {
                RangeDeclaration declaration = new RangeDeclaration(queryContext);
                declaration.type = type;
                currentDeclaration = declaration;
            }
            // Derived path expression (for subqueries)
            else {
                currentDeclaration = new DerivedDeclaration(queryContext);
            }

            currentDeclaration.rootPath = rootPath;
        }

        @Override
        public void visit(DeleteClause expression) {
            try {
                expression.getRangeVariableDeclaration().accept(this);
            }
            finally {
                currentDeclaration = null;
            }
        }

        @Override
        public void visit(DeleteStatement expression) {
            expression.getDeleteClause().accept(this);
        }

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

        @Override
        public void visit(IdentificationVariableDeclaration expression) {

            try {
                // Visit the RangeVariableDeclaration, it will create the right Declaration
                expression.getRangeVariableDeclaration().accept(this);
                currentDeclaration.declarationExpression = expression;

                // Now visit the JOIN expressions
                expression.getJoins().accept(this);
            }
            finally {
                currentDeclaration = null;
            }
        }

        @Override
        public void visit(Join expression) {

            ((AbstractRangeDeclaration) currentDeclaration).addJoin(expression);

            if (!expression.hasFetch() || expression.hasIdentificationVariable()) {
                IdentificationVariable identificationVariable = (IdentificationVariable) expression.getIdentificationVariable();

                JoinDeclaration declaration = new JoinDeclaration(queryContext);
                declaration.baseExpression = expression;
                declaration.identificationVariable = identificationVariable;
                declarations.add(declaration);
            }
        }

        @Override
        public void visit(JPQLExpression expression) {
            expression.getQueryStatement().accept(this);
        }

        @Override
        public void visit(RangeVariableDeclaration expression) {

            // Traverse the "root" object, it will create the right Declaration
            buildingDeclaration = true;
            expression.getRootObject().accept(this);
            buildingDeclaration = false;

            // Cache more information
            currentDeclaration.identificationVariable = (IdentificationVariable) expression.getIdentificationVariable();
            currentDeclaration.baseExpression = expression;
            declarations.add(currentDeclaration);

            // This range variable declaration is the first defined,
            // it is then the base declaration
            if (baseDeclaration == null) {
                baseDeclaration = currentDeclaration;
            }
        }

        @Override
        public void visit(SelectStatement expression) {
            expression.getFromClause().accept(this);
        }

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

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

        @Override
        public void visit(SimpleSelectStatement expression) {

            // The parent query is using a subquery in the FROM clause
            if (buildingDeclaration) {
                currentDeclaration = new SubqueryDeclaration(queryContext);
                currentDeclaration.rootPath = ExpressionTools.EMPTY_STRING;
            }
            // Simply traversing the tree to create the declarations
            else {
                expression.getFromClause().accept(this);
            }
        }

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

        @Override
        public void visit(TableVariableDeclaration expression) {

            TableDeclaration declaration = new TableDeclaration(queryContext);
            declaration.declarationExpression  = expression;
            declaration.baseExpression         = expression.getTableExpression();
            declaration.rootPath               = declaration.baseExpression.toParsedText();
            declaration.identificationVariable = (IdentificationVariable) expression.getIdentificationVariable();
            declarations.add(declaration);
        }

        @Override
        public void visit(UpdateClause expression) {
            try {
                expression.getRangeVariableDeclaration().accept(this);
            }
            finally {
                currentDeclaration = null;
            }
        }

        @Override
        public void visit(UpdateStatement expression) {
            expression.getUpdateClause().accept(this);
        }
    }

    private static class QualifyRangeDeclarationVisitor extends AbstractEclipseLinkExpressionVisitor {

        /**
         * The {@link Declaration} being modified.
         */
        AbstractRangeDeclaration declaration;

        /**
         * The identification variable coming from the parent identification variable declaration.
         */
        String outerVariableName;

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

        @Override
        public void visit(CollectionValuedPathExpression expression) {
            // Create the path because CollectionValuedPathExpression.toParsedText()
            // does not contain the virtual identification variable
            StringBuilder rootPath = new StringBuilder();
            rootPath.append(outerVariableName);
            rootPath.append(".");
            rootPath.append(expression.toParsedText());
            declaration.rootPath = rootPath.toString();
        }

        @Override
        public void visit(IdentificationVariableDeclaration expression) {
            expression.getRangeVariableDeclaration().accept(this);
            declaration.declarationExpression = expression;
        }

        @Override
        public void visit(RangeVariableDeclaration expression) {

            DerivedDeclaration derivedDeclaration = new DerivedDeclaration(queryContext);
            derivedDeclaration.joins                       = declaration.joins;
            derivedDeclaration.rootPath                    = declaration.rootPath;
            derivedDeclaration.baseExpression              = declaration.baseExpression;
            derivedDeclaration.identificationVariable      = declaration.identificationVariable;
            declaration = derivedDeclaration;

            expression.setVirtualIdentificationVariable(outerVariableName, declaration.rootPath);
            expression.getRootObject().accept(this);
        }
    }

    /**
     * This visitor traverses the <code><b>SELECT</b></code> clause and retrieves the result variables.
     */
    private static class ResultVariableVisitor extends AbstractEclipseLinkExpressionVisitor {

        Set<IdentificationVariable> resultVariables;

        /**
         * Creates a new <code>ResultVariableVisitor</code>.
         */
        public ResultVariableVisitor() {
            super();
            resultVariables = new HashSet<>();
        }

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

        @Override
        public void visit(JPQLExpression expression) {
            expression.getQueryStatement().accept(this);
        }

        @Override
        public void visit(ResultVariable expression) {
            IdentificationVariable identificationVariable = (IdentificationVariable) expression.getResultVariable();
            resultVariables.add(identificationVariable);
        }

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

        @Override
        public void visit(SelectStatement expression) {
            expression.getSelectClause().accept(this);
        }
    }
}
