/*
 * 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
//
package org.eclipse.persistence.jpa.jpql;

import org.eclipse.persistence.jpa.jpql.AbstractEclipseLinkSemanticValidator.EclipseLinkOwningClauseVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AbstractEclipseLinkExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AbstractSelectClause;
import org.eclipse.persistence.jpa.jpql.parser.AsOfClause;
import org.eclipse.persistence.jpa.jpql.parser.CastExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConnectByClause;
import org.eclipse.persistence.jpa.jpql.parser.DatabaseType;
import org.eclipse.persistence.jpa.jpql.parser.DatabaseTypeFactory;
import org.eclipse.persistence.jpa.jpql.parser.DefaultEclipseLinkJPQLGrammar;
import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
import org.eclipse.persistence.jpa.jpql.parser.ExtractExpression;
import org.eclipse.persistence.jpa.jpql.parser.HierarchicalQueryClause;
import org.eclipse.persistence.jpa.jpql.parser.InExpression;
import org.eclipse.persistence.jpa.jpql.parser.InputParameter;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar;
import org.eclipse.persistence.jpa.jpql.parser.OrderSiblingsByClause;
import org.eclipse.persistence.jpa.jpql.parser.PatternValueBNF;
import org.eclipse.persistence.jpa.jpql.parser.RegexpExpression;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectClause;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.StartWithClause;
import org.eclipse.persistence.jpa.jpql.parser.StringExpressionBNF;
import org.eclipse.persistence.jpa.jpql.parser.TableExpression;
import org.eclipse.persistence.jpa.jpql.parser.TableVariableDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.UnionClause;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.*;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.*;

/**
 * This validator adds EclipseLink extension over what the JPA functional specification had defined.
 * <p>
 * Provisional API: This interface is part of an interim API that is still under development and
 * expected to change significantly before reaching stability. It is available at this early stage
 * to solicit feedback from pioneering adopters on the understanding that any code that uses this
 * API will almost certainly be broken (repeatedly) as the API evolves.
 *
 * @version 2.5
 * @since 2.4
 * @author Pascal Filion
 */
public class EclipseLinkGrammarValidator extends AbstractGrammarValidator
        implements EclipseLinkExpressionVisitor {

    private InExpressionVisitor inExpressionVisitor;
    private InExpressionWithNestedArrayVisitor inExpressionWithNestedArrayVisitor;

    /**
     * Creates a new <code>EclipseLinkGrammarValidator</code>.
     *
     * @param jpqlGrammar The {@link JPQLGrammar} that defines how the JPQL query was parsed
     */
    public EclipseLinkGrammarValidator(JPQLGrammar jpqlGrammar) {
        super(jpqlGrammar);
    }

    protected AbstractSingleEncapsulatedExpressionHelper<CastExpression> buildCastExpressionHelper() {
        return new AbstractSingleEncapsulatedExpressionHelper<CastExpression>(this) {
            @Override
            protected String encapsulatedExpressionInvalidKey(CastExpression expression) {
                return CastExpression_InvalidExpression;
            }
            @Override
            protected String encapsulatedExpressionMissingKey(CastExpression expression) {
                return CastExpression_MissingExpression;
            }
            @Override
            public String leftParenthesisMissingKey(CastExpression expression) {
                return CastExpression_MissingLeftParenthesis;
            }
            @Override
            public String rightParenthesisMissingKey(CastExpression expression) {
                return CastExpression_MissingRightParenthesis;
            }
        };
    }

    protected AbstractDoubleEncapsulatedExpressionHelper<DatabaseType> buildDatabaseTypeHelper() {
        return new AbstractDoubleEncapsulatedExpressionHelper<DatabaseType>(this) {
            @Override
            protected String firstExpressionInvalidKey() {
                return DatabaseType_InvalidFirstExpression;
            }
            @Override
            protected String firstExpressionMissingKey() {
                return DatabaseType_MissingFirstExpression;
            }
            @Override
            protected boolean hasComma(DatabaseType expression) {
                // If the second expression is not specified, then the comma is not needed
                return expression.hasComma() ||
                        !expression.hasSecondExpression();
            }
            @Override
            protected boolean hasFirstExpression(DatabaseType expression) {
                return !expression.hasLeftParenthesis() ||
                        expression.hasFirstExpression();
            }
            @Override
            public boolean hasLeftParenthesis(DatabaseType expression) {
                if (expression.hasLeftParenthesis()) {
                    return true;
                }
                // The parenthesis are optional unless one the following
                // items is specified, then '(' is required
                return !(expression.hasFirstExpression()  ||
                        expression.hasComma()            ||
                        expression.hasSecondExpression() ||
                        expression.hasRightParenthesis());
            }
            @Override
            public boolean hasRightParenthesis(DatabaseType expression) {
                if (expression.hasRightParenthesis()) {
                    return true;
                }
                // The parenthesis are optional unless one the following
                // items is specified, then ')' is required
                return !(expression.hasLeftParenthesis()  ||
                        expression.hasFirstExpression()  ||
                        expression.hasComma()            ||
                        expression.hasSecondExpression());
            }
            @Override
            protected boolean hasSecondExpression(DatabaseType expression) {
                return !expression.hasComma() ||
                        expression.hasSecondExpression();
            }
            @Override
            public String leftParenthesisMissingKey(DatabaseType expression) {
                return DatabaseType_MissingLeftParenthesis;
            }
            @Override
            protected String missingCommaKey() {
                return DatabaseType_MissingComma;
            }
            @Override
            public String rightParenthesisMissingKey(DatabaseType expression) {
                return DatabaseType_MissingRightParenthesis;
            }
            @Override
            protected String secondExpressionInvalidKey() {
                return DatabaseType_InvalidSecondExpression;
            }
            @Override
            protected String secondExpressionMissingKey() {
                return DatabaseType_MissingSecondExpression;
            }
        };
    }

    protected AbstractSingleEncapsulatedExpressionHelper<ExtractExpression> buildExtractExpressionHelper() {
        return new AbstractSingleEncapsulatedExpressionHelper<ExtractExpression>(this) {
            @Override
            protected String encapsulatedExpressionInvalidKey(ExtractExpression expression) {
                return ExtractExpression_InvalidExpression;
            }
            @Override
            protected String encapsulatedExpressionMissingKey(ExtractExpression expression) {
                return ExtractExpression_MissingExpression;
            }
            @Override
            public String leftParenthesisMissingKey(ExtractExpression expression) {
                return ExtractExpression_MissingLeftParenthesis;
            }
            @Override
            protected int lengthBeforeEncapsulatedExpression(ExtractExpression expression) {
                return expression.getDatePart().length() +
                        (expression.hasSpaceAfterDatePart() ? 1 : 0) +
                        (expression.hasFrom() ? 4 /* FROM */ : 0) +
                        (expression.hasSpaceAfterFrom() ? 1 : 0);
            }
            @Override
            public String rightParenthesisMissingKey(ExtractExpression expression) {
                return ExtractExpression_MissingRightParenthesis;
            }
        };
    }

    protected InExpressionVisitor buildInExpressionVisitor() {
        return new InExpressionVisitor();
    }

    protected InExpressionWithNestedArrayVisitor buildInExpressionWithNestedArrayVisitor() {
        return new InExpressionWithNestedArrayVisitor(this);
    }

    @Override
    protected LiteralVisitor buildLiteralVisitor() {
        return new EclipseLinkLiteralVisitor();
    }

    @Override
    protected OwningClauseVisitor buildOwningClauseVisitor() {
        return new EclipseLinkOwningClauseVisitor();
    }

    protected AbstractSingleEncapsulatedExpressionHelper<TableExpression> buildTableExpressionHelper() {
        return new AbstractSingleEncapsulatedExpressionHelper<TableExpression>(this) {
            @Override
            protected String encapsulatedExpressionInvalidKey(TableExpression expression) {
                return TableExpression_InvalidExpression;
            }
            @Override
            protected String encapsulatedExpressionMissingKey(TableExpression expression) {
                return TableExpression_MissingExpression;
            }
            @Override
            public String leftParenthesisMissingKey(TableExpression expression) {
                return TableExpression_MissingLeftParenthesis;
            }
            @Override
            public String rightParenthesisMissingKey(TableExpression expression) {
                return TableExpression_MissingRightParenthesis;
            }
        };
    }

    protected AbstractSingleEncapsulatedExpressionHelper<CastExpression> castExpressionHelper() {
        AbstractSingleEncapsulatedExpressionHelper<CastExpression> helper = getHelper(CAST);
        if (helper == null) {
            helper = buildCastExpressionHelper();
            registerHelper(CAST, helper);
        }
        return helper;
    }

    protected AbstractDoubleEncapsulatedExpressionHelper<DatabaseType> databaseTypeHelper() {
        AbstractDoubleEncapsulatedExpressionHelper<DatabaseType> helper = getHelper(DatabaseTypeFactory.ID);
        if (helper == null) {
            helper = buildDatabaseTypeHelper();
            registerHelper(DatabaseTypeFactory.ID, helper);
        }
        return helper;
    }

    protected AbstractSingleEncapsulatedExpressionHelper<ExtractExpression> extractExpressionHelper() {
        AbstractSingleEncapsulatedExpressionHelper<ExtractExpression> helper = getHelper(EXTRACT);
        if (helper == null) {
            helper = buildExtractExpressionHelper();
            registerHelper(EXTRACT, helper);
        }
        return helper;
    }

    protected InExpressionVisitor getInExpressionVisitor() {
        if (inExpressionVisitor == null) {
            inExpressionVisitor = buildInExpressionVisitor();
        }
        return inExpressionVisitor;
    }

    protected InExpressionWithNestedArrayVisitor getInExpressionWithNestedArray() {
        if (inExpressionWithNestedArrayVisitor == null) {
            inExpressionWithNestedArrayVisitor = buildInExpressionWithNestedArrayVisitor();
        }
        return inExpressionWithNestedArrayVisitor;
    }

    @Override
    protected EclipseLinkOwningClauseVisitor getOwningClauseVisitor() {
        return (EclipseLinkOwningClauseVisitor) super.getOwningClauseVisitor();
    }

    /**
     * Determines whether the persistence provider is EclipseLink or not.
     *
     * @return <code>true</code> if the persistence provider is EclipseLink; <code>false</code> otherwise
     */
    protected final boolean isEclipseLink() {
        return DefaultEclipseLinkJPQLGrammar.PROVIDER_NAME.equals(getProvider());
    }

    /**
     * Determines whether the subquery is part of an <code><b>IN</b></code> expression where the
     * left expression is a nested array.
     *
     * @param expression The {@link SimpleSelectClause} of the subquery
     * @return <code>true</code> if the subquery is in an <code><b>IN</b></code> expression and its
     * left expression is a nested array
     */
    protected boolean isInExpressionWithNestedArray(SimpleSelectClause expression) {
        InExpressionWithNestedArrayVisitor visitor = getInExpressionWithNestedArray();
        try {
            expression.accept(visitor);
            return visitor.valid;
        }
        finally {
            visitor.valid = false;
        }
    }

    @Override
    protected boolean isInputParameterInValidLocation(InputParameter expression) {
        return true;
    }

    @Override
    protected boolean isJoinFetchIdentifiable() {
        EclipseLinkVersion version = EclipseLinkVersion.value(getGrammar().getProviderVersion());
        return version.isNewerThanOrEqual(EclipseLinkVersion.VERSION_2_4);
    }

    @Override
    protected boolean isMultipleSubquerySelectItemsAllowed(SimpleSelectClause expression) {
        return isInExpressionWithNestedArray(expression);
    }

    protected boolean isOwnedByInExpression(Expression expression) {
        InExpressionVisitor visitor = getInExpressionVisitor();
        expression.accept(visitor);
        return visitor.expression != null;
    }

    /**
     * Determines whether the given {@link Expression} is a child of the <b>UNION</b> clause.
     *
     * @param expression The {@link Expression} to visit its parent hierarchy up to the clause
     * @return <code>true</code> if the first parent being a clause is the <b>UNION</b> clause;
     * <code>false</code> otherwise
     */
    protected boolean isOwnedByUnionClause(Expression expression) {
        EclipseLinkOwningClauseVisitor visitor = getOwningClauseVisitor();
        try {
            expression.accept(visitor);
            return visitor.unionClause != null;
        }
        finally {
            visitor.dispose();
        }
    }

    @Override
    protected boolean isSubqueryAllowedAnywhere() {
        EclipseLinkVersion version = EclipseLinkVersion.value(getProviderVersion());
        return version.isNewerThanOrEqual(EclipseLinkVersion.VERSION_2_4);
    }

    protected AbstractSingleEncapsulatedExpressionHelper<TableExpression> tableExpressionHelper() {
        AbstractSingleEncapsulatedExpressionHelper<TableExpression> helper = getHelper(TABLE);
        if (helper == null) {
            helper = buildTableExpressionHelper();
            registerHelper(TABLE, helper);
        }
        return helper;
    }

    @Override
    protected void validateAbstractSelectClause(AbstractSelectClause expression,
                                                boolean multipleSelectItemsAllowed) {

        // A subquery can have multiple select items if it is
        // - used as a "root" object in the top-level FROM clause
        // - defined in a UNION clause
        // - used in an IN expression
        // If the flag is false, then the SELECT clause is from a subquery
        if (!multipleSelectItemsAllowed) {
            Expression parent = expression.getParent();
            multipleSelectItemsAllowed = isOwnedByFromClause  (parent) ||
                    isOwnedByUnionClause (parent) ||
                    isOwnedByInExpression(parent);
        }

        super.validateAbstractSelectClause(expression, multipleSelectItemsAllowed);
    }

    @Override
    public void visit(AsOfClause expression) {
    }

    @Override
    public void visit(CastExpression expression) {

        // Wrong JPA version
        if (!isEclipseLink()) {
            addProblem(expression, CastExpression_InvalidJPAVersion);
        }
        else {

            validateAbstractSingleEncapsulatedExpression(expression, castExpressionHelper());

            // Database type
            if (expression.hasExpression() || expression.hasAs()) {

                // Missing database type
                if (!expression.hasDatabaseType()) {

                    int startPosition = position(expression) +
                            4 /* CAST */ +
                            (expression.hasLeftParenthesis() ? 1 : 0) +
                            length(expression.getExpression()) +
                            (expression.hasSpaceAfterExpression() ? 1 : 0) +
                            (expression.hasAs() ? 2 : 0) +
                            (expression.hasSpaceAfterAs() ? 1 : 0);

                    addProblem(expression, startPosition, CastExpression_MissingDatabaseType);
                }
                // Validate database type
                else {
                    expression.getDatabaseType().accept(this);
                }
            }
        }
    }

    @Override
    public void visit(ConnectByClause expression) {
        // TODO: 2.5
    }

    @Override
    public void visit(DatabaseType expression) {
        validateAbstractDoubleEncapsulatedExpression(expression, databaseTypeHelper());
    }

    @Override
    public void visit(ExtractExpression expression) {

        // Wrong JPA version
        if (!isEclipseLink()) {
            addProblem(expression, ExtractExpression_InvalidJPAVersion);
        }
        else {

            validateAbstractSingleEncapsulatedExpression(expression, extractExpressionHelper());

            // Missing date part
            if (expression.hasLeftParenthesis() && !expression.hasDatePart()) {

                int startPosition = position(expression) +
                        7 /* EXTRACT */ +
                        (expression.hasLeftParenthesis() ? 1 : 0);

                addProblem(expression, startPosition, ExtractExpression_MissingDatePart);
            }
        }
    }

    @Override
    public void visit(HierarchicalQueryClause expression) {
        // TODO: 2.5
    }

    @Override
    public void visit(OrderSiblingsByClause expression) {
        // TODO
    }

    @Override
    public void visit(RegexpExpression expression) {

        // Wrong JPA version
        if (!isEclipseLink()) {
            addProblem(expression, RegexpExpression_InvalidJPAVersion);
        }
        else {

            // Missing string expression
            if (!expression.hasStringExpression()) {

                int startPosition = position(expression);
                int endPosition   = startPosition;

                addProblem(
                        expression,
                        startPosition,
                        endPosition,
                        RegexpExpression_MissingStringExpression
                );
            }
            else {
                Expression stringExpression = expression.getStringExpression();

                // Invalid string expression
                if (!isValid(stringExpression, StringExpressionBNF.ID)) {

                    int startPosition = position(stringExpression);
                    int endPosition   = startPosition + length(stringExpression);

                    addProblem(
                            expression,
                            startPosition,
                            endPosition,
                            RegexpExpression_InvalidStringExpression
                    );
                }
                // Validate string expression
                else {
                    stringExpression.accept(this);
                }
            }

            // Missing pattern value
            if (!expression.hasPatternValue()) {

                int startPosition = position(expression) +
                        length(expression.getStringExpression()) +
                        (expression.hasSpaceAfterStringExpression() ? 1 : 0) +
                        6 /* REGEXP */ +
                        (expression.hasSpaceAfterIdentifier() ? 1 : 0);

                int endPosition = startPosition;

                addProblem(expression, startPosition, endPosition, RegexpExpression_MissingPatternValue);
            }
            else {
                Expression patternValue = expression.getStringExpression();

                // Invalid string expression
                if (!isValid(patternValue, PatternValueBNF.ID)) {

                    int startPosition = position(expression) +
                            length(expression.getStringExpression()) +
                            (expression.hasSpaceAfterStringExpression() ? 1 : 0) +
                            6 /* REGEXP */ +
                            (expression.hasSpaceAfterIdentifier() ? 1 : 0);

                    int endPosition = startPosition + length(patternValue);

                    addProblem(
                            expression,
                            startPosition,
                            endPosition,
                            RegexpExpression_InvalidPatternValue
                    );
                }
                // Validate pattern value
                else {
                    patternValue.accept(this);
                }
            }
        }
    }

    @Override
    public void visit(StartWithClause expression) {
        // TODO: 2.5
    }

    @Override
    public void visit(TableExpression expression) {
        validateAbstractSingleEncapsulatedExpression(expression, tableExpressionHelper());
    }

    @Override
    public void visit(TableVariableDeclaration expression) {

        // Wrong JPA version
        if (!isEclipseLink()) {
            addProblem(expression, TableVariableDeclaration_InvalidJPAVersion);
        }
        else {

            TableExpression tableExpression = expression.getTableExpression();

            // Validate the table expression
            tableExpression.accept(this);

            // The identification variable is missing
            if (!expression.hasIdentificationVariable()) {

                int startPosition = position(expression) +
                        length(tableExpression) +
                        (expression.hasSpaceAfterTableExpression() ? 1 : 0) +
                        (expression.hasAs() ? 2 : 0) +
                        (expression.hasSpaceAfterAs() ? 1 : 0);

                addProblem(expression, startPosition, TableVariableDeclaration_MissingIdentificationVariable);
            }
            // Validate the identification variable
            else {
                expression.getIdentificationVariable().accept(this);
            }
        }
    }

    @Override
    public void visit(UnionClause expression) {

        // Wrong JPA version
        if (!isEclipseLink()) {
            addProblem(expression, UnionClause_InvalidJPAVersion);
        }
        // Missing subquery
        else if (!expression.hasQuery()) {

            int startPosition = position(expression) +
                    expression.getIdentifier().length() +
                    (expression.hasSpaceAfterIdentifier() ? 1 : 0) +
                    (expression.hasAll() ? 3 : 0) +
                    (expression.hasSpaceAfterAll() ? 1 : 0);

            addProblem(expression, startPosition, UnionClause_MissingExpression);
        }
        // Validate the subquery
        else {
            expression.getQuery().accept(this);
        }
    }

    // Made static for performance reasons.
    protected static class InExpressionVisitor extends AbstractEclipseLinkExpressionVisitor {

        protected InExpression expression;

        /**
         * Default constructor.
         */
        protected InExpressionVisitor() {
        }

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

    // Made static final for performance reasons.
    protected static final class InExpressionWithNestedArrayVisitor extends AbstractEclipseLinkExpressionVisitor {

        private final EclipseLinkGrammarValidator visitor;

        protected InExpressionWithNestedArrayVisitor(EclipseLinkGrammarValidator visitor) {
            this.visitor = visitor;
        }

        /**
         * Determines whether the left expression of an <code><b>IN</b></code> expression is a nested
         * array when the <code><b>IN</b></code> item is a subquery.
         */
        public boolean valid;

        @Override
        public void visit(InExpression expression) {
            valid = visitor.isNestedArray(expression.getExpression());
        }

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

        @Override
        public void visit(SimpleSelectStatement expression) {
            expression.getParent().accept(this);
        }
    }
}