/*
 * 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</code>" <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
     */
    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);
        }
    }
}
