/*
 * Copyright (c) 2006, 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
//
//     09/02/2019-3.0 Alexandre Jacob
//        - 527415: Fix code when locale is tr, az or lt
package org.eclipse.persistence.jpa.jpql.parser;

import java.util.Locale;

/**
 * This visitor makes sure that all path expressions are fully qualified with a "virtual"
 * identification variable if the range variable declaration does not define one. This only applies
 * to an <code><b>UPDATE</b></code> or <code><b>DELETE</b></code> queries.
 *
 * @version 2.5
 * @since 2.3
 * @author Pascal Filion
 */
public final class FullyQualifyPathExpressionVisitor extends AbstractTraverseChildrenVisitor {

    /**
     * The "virtual" identification variable if none was defined.
     */
    private String variableName;

    /**
     * Caches this visitor, which is used to determine if the general identification variable is not
     * a map key, map value or map entry expression.
     */
    private GeneralIdentificationVariableVisitor visitor;

    private GeneralIdentificationVariableVisitor generalIdentificationVariableVisitor() {
        if (visitor == null) {
            visitor = new GeneralIdentificationVariableVisitor();
        }
        return visitor;
    }

    @Override
    public void visit(AbstractSchemaName expression) {
        // The "virtual" variable name will be the entity name
        variableName = expression.toActualText().toLowerCase(Locale.ROOT);
    }

    @Override
    public void visit(CollectionMemberDeclaration expression) {
        // Do nothing, prevent to do anything for invalid queries
    }

    @Override
    public void visit(CollectionValuedPathExpression expression) {
        visitAbstractPathExpression(expression);
    }

    @Override
    public void visit(DeleteClause expression) {
        expression.getRangeVariableDeclaration().accept(this);
    }

    @Override
    public void visit(DeleteStatement expression) {

        expression.getDeleteClause().accept(this);

        // Don't traverse the tree if the path expressions don't need to be virtually qualified
        if ((variableName != null) && expression.hasWhereClause()) {
            expression.getWhereClause().accept(this);
        }
    }

    @Override
    public void visit(IdentificationVariable expression) {

        // A null check is required because the query could be invalid/incomplete
        // The identification variable should become a state field path expression
        expression.setVirtualIdentificationVariable(variableName);
    }

    @Override
    public void visit(Join expression) {
        // Do nothing, prevent to do anything for invalid queries
    }

    @Override
    public void visit(RangeVariableDeclaration expression) {

        // The "root" object does not have an identification variable,
        // then we'll assume all path expressions are unqualified
        if (!expression.hasIdentificationVariable()) {
            expression.getRootObject().accept(this);
            expression.setVirtualIdentificationVariable(variableName);
        }
    }

    @Override
    public void visit(SelectStatement expression) {
        // Nothing to do because a SELECT query has to have its path expressions fully qualified
    }

    @Override
    public void visit(SimpleSelectStatement expression) {
        // Nothing to do because a subquery query has to have its path expressions fully qualified
    }

    @Override
    public void visit(StateFieldPathExpression expression) {
        // A null check is required because the query could be invalid/incomplete
        visitAbstractPathExpression(expression);
    }

    @Override
    public void visit(UpdateClause expression) {

        expression.getRangeVariableDeclaration().accept(this);

        // Don't traverse the tree if the path expressions don't need to be virtually qualified
        if ((variableName != null) && expression.hasUpdateItems()) {
            expression.getUpdateItems().accept(this);
        }
    }

    @Override
    public void visit(UpdateStatement expression) {

        expression.getUpdateClause().accept(this);

        // Don't traverse the tree if the path expressions don't need to be virtually qualified
        if ((variableName != null) && expression.hasWhereClause()) {
            expression.getWhereClause().accept(this);
        }
    }

    private void visitAbstractPathExpression(AbstractPathExpression expression) {

        if (!expression.startsWithDot()) {

            // Visit the general identification variable to make sure it's not a map key, map entry
            // or map value expression
            GeneralIdentificationVariableVisitor visitor = generalIdentificationVariableVisitor();
            expression.getIdentificationVariable().accept(visitor);

            if (visitor.expression == null) {
                expression.setVirtualIdentificationVariable(variableName);
            }
        }
    }

    // Made static final for performance reasons.
    private static final class GeneralIdentificationVariableVisitor extends AbstractExpressionVisitor {

        /**
         * The {@link Expression} that was visited, which is a general identification variable but is
         * not a identification variable, it's either a map value, map key or map value expression.
         */
        private Expression expression;

        @Override
        public void visit(EntryExpression expression) {
            this.expression = expression;
        }

        @Override
        public void visit(KeyExpression expression) {
            this.expression = expression;
        }

        @Override
        public void visit(ValueExpression expression) {
            this.expression = expression;
        }
    }
}
