/*
 * 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.parser.AbstractEclipseLinkExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AnonymousExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AsOfClause;
import org.eclipse.persistence.jpa.jpql.parser.BadExpression;
import org.eclipse.persistence.jpa.jpql.parser.CastExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionValuedPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConnectByClause;
import org.eclipse.persistence.jpa.jpql.parser.DatabaseType;
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.FunctionExpression;
import org.eclipse.persistence.jpa.jpql.parser.HierarchicalQueryClause;
import org.eclipse.persistence.jpa.jpql.parser.InExpression;
import org.eclipse.persistence.jpa.jpql.parser.NullExpression;
import org.eclipse.persistence.jpa.jpql.parser.OrderSiblingsByClause;
import org.eclipse.persistence.jpa.jpql.parser.RangeVariableDeclaration;
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.StateFieldPathExpression;
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.*;

/**
 * This validator is responsible to gather the problems found in a JPQL query by validating the
 * content to make sure it is semantically valid for EclipseLink. The grammar is not validated by
 * this visitor.
 * <p>
 * For instance, the function <b>AVG</b> accepts a state field path. The property it represents has
 * to be of numeric type. <b>AVG(e.name)</b> is parsable but is not semantically valid because the
 * type of name is a string (the property signature is: "<code>private String name</code>").
 * <p>
 * <b>Note:</b> EclipseLink does not validate types, but leaves it to the database. This is because
 * some databases such as Oracle allow different types to different functions and perform implicit
 * type conversion. i.e. <code>CONCAT('test', 2)</code> returns <code>'test2'</code>. Also the
 * <b>FUNC</b> function has an unknown type, so should be allowed with any function.
 * <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.
 *
 * @see EclipseLinkGrammarValidator
 *
 * @version 2.5.1
 * @since 2.4
 * @author Pascal Filion
 */
public class AbstractEclipseLinkSemanticValidator extends AbstractSemanticValidator
                                                  implements EclipseLinkExpressionVisitor {

    /**
     * The following extension can be used to give access to non-JPA metadata artifacts, such as
     * database tables and columns.
     */
    private EclipseLinkSemanticValidatorExtension extension;

    /**
     * This visitor calculates the number of items the subquery <code><b>SELECT</b></code> clause has.
     */
    private SubquerySelectItemCalculator subquerySelectItemCalculator;

    /**
     * This visitor determines if the {@link Expression} being visited is a {@link TableExpression}.
     */
    private TableExpressionVisitor tableExpressionVisitor;

    /**
     * Creates a new <code>AbstractEclipseLinkSemanticValidator</code>.
     *
     * @param helper The given helper allows this validator to access the JPA artifacts without using
     * Hermes SPI
     * @param extension The following extension can be used to give access to non-JPA metadata
     * artifacts, such as database tables and columns
     * @exception NullPointerException The given {@link SemanticValidatorHelper} cannot be <code>null</code>
     */
    protected AbstractEclipseLinkSemanticValidator(SemanticValidatorHelper helper,
                                                   EclipseLinkSemanticValidatorExtension extension) {

        super(helper);
        this.extension = extension;
    }

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

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

    protected SubquerySelectItemCalculator buildSubquerySelectItemCalculator() {
        return new SubquerySelectItemCalculator();
    }

    protected TableExpressionVisitor buildTableExpressionVisitor() {
        return new TableExpressionVisitor();
    }

    @Override
    protected TopLevelFirstDeclarationVisitor buildTopLevelFirstDeclarationVisitor() {
        return new TopLevelFirstDeclarationVisitor(this);
    }

    protected JPQLQueryDeclaration getDeclaration(String variableName) {

        for (JPQLQueryDeclaration declaration : helper.getAllDeclarations()) {

            if (declaration.getVariableName().equalsIgnoreCase(variableName)) {
                return declaration;
            }
        }

        return null;
    }

    /**
     * Returns the extension that gives access to non-JPA metadata artifacts, such as database tables
     * and columns.
     *
     * @return An extension giving access to non-JPA metadata artifacts or {@link
     * EclipseLinkSemanticValidatorExtension#NULL_EXTENSION} if no extension was provided
     */
    protected EclipseLinkSemanticValidatorExtension getExtension() {
        return extension;
    }

    protected SubquerySelectItemCalculator getSubquerySelectItemCalculator() {
        if (subquerySelectItemCalculator == null) {
            subquerySelectItemCalculator = buildSubquerySelectItemCalculator();
        }
        return subquerySelectItemCalculator;
    }

    protected TableExpressionVisitor getTableExpressionVisitor() {
        if (tableExpressionVisitor == null) {
            tableExpressionVisitor = buildTableExpressionVisitor();
        }
        return tableExpressionVisitor;
    }

    protected boolean isTableExpression(Expression expression) {
        TableExpressionVisitor visitor = getTableExpressionVisitor();
        try {
            visitor.expression = expression;
            expression.accept(visitor);
            return visitor.valid;
        }
        finally {
            visitor.valid = false;
            visitor.expression = null;
        }
    }

    @Override
    protected PathType selectClausePathExpressionPathType() {
        return PathType.ANY_FIELD_INCLUDING_COLLECTION;
    }

    /**
     * Retrieves the number of select items the given subquery has.
     *
     * @param subquery The {@link Expression} to visit, which should represents a subquery
     * @return The number of select items or 0 if the subquery is malformed or incomplete
     */
    protected int subquerySelectItemCount(Expression subquery) {
        SubquerySelectItemCalculator visitor = getSubquerySelectItemCalculator();
        try {
            visitor.count = 0;
            subquery.accept(visitor);
            return visitor.count;
        }
        finally {
            visitor.count = 0;
        }
    }

    @Override
    protected void validateFunctionExpression(FunctionExpression expression) {
        super.validateFunctionExpression(expression);

        // No need to validate if no extension was provided
        // Validate the column name
        if (extension != EclipseLinkSemanticValidatorExtension.NULL_EXTENSION &&
           (expression.getIdentifier() == Expression.COLUMN) &&
            expression.hasExpression()) {

            String columnName = expression.getUnquotedFunctionName();
            String variableName = literal(expression.getExpression(), LiteralType.IDENTIFICATION_VARIABLE);

            if (ExpressionTools.stringIsNotEmpty(variableName) &&
                ExpressionTools.stringIsNotEmpty(columnName)) {

                // Retrieve the declaration associated with the identification variable
                JPQLQueryDeclaration declaration = getDeclaration(variableName);

                // Only a range variable declaration can be used
                if (declaration.getType().isRange()) {
                    String entityName = literal(declaration.getBaseExpression(), LiteralType.ABSTRACT_SCHEMA_NAME);

                    if (entityName != ExpressionTools.EMPTY_STRING) {

                        // Retrieve the primary table of the entity
                        String tableName = extension.getEntityTable(entityName);

                        // The column is not on the primary table
                        if (ExpressionTools.stringIsNotEmpty(tableName) &&
                            !extension.columnExists(tableName, expression.getUnquotedFunctionName())) {

                            int startPosition = position(expression) +
                                                Expression.COLUMN.length() +
                                                (expression.hasLeftParenthesis() ? 1 : 0);

                            int endPosition = startPosition +
                                              expression.getFunctionName().length();

                            addProblem(
                                expression,
                                startPosition,
                                endPosition,
                                FunctionExpression_UnknownColumn,
                                columnName,
                                tableName
                            );
                        }
                    }
                }
            }
        }
    }

    @Override
    protected void validateInExpression(InExpression expression) {
        super.validateInExpression(expression);

        // Make sure the number of items matches if the left expression
        // is a nested array and the IN items expression is a subquery
        Expression inItems = expression.getInItems();

        if (isSubquery(inItems)) {
            int nestedArraySize = nestedArraySize(expression.getExpression());
            int subquerySelectItemsSize = subquerySelectItemCount(inItems);

            if ((nestedArraySize  > -1) && (subquerySelectItemsSize != nestedArraySize) ||
                (nestedArraySize == -1) && (subquerySelectItemsSize  > 1)) {

                addProblem(expression, InExpression_InvalidItemCount);
            }
        }
    }

    @Override
    protected void validateRangeVariableDeclarationRootObject(RangeVariableDeclaration expression) {

        Expression rootObject = expression.getRootObject();

        // Special case, the path expression could be a fully qualified class name,
        // make sure to not validate it as collection-valued path expression
        CollectionValuedPathExpression pathExpression = getCollectionValuedPathExpression(rootObject);

        if (pathExpression != null) {
            String path = pathExpression.toActualText();

            // The path expression is not a fully qualified class name
            if (helper.getType(path) == null) {
                pathExpression.accept(this);
            }
        }
        else {
            rootObject.accept(this);
        }
    }

    @Override
    protected PathType validPathExpressionTypeForCountFunction() {
        return PathType.ANY_FIELD_INCLUDING_COLLECTION;
    }

    @Override
    protected PathType validPathExpressionTypeForInExpression() {
        // Loosen up the JPA spec restriction because ANTLR parser used to allow it
        return PathType.ANY_FIELD_INCLUDING_COLLECTION;
    }

    @Override
    protected PathType validPathExpressionTypeForInItem() {
        return PathType.ANY_FIELD_INCLUDING_COLLECTION;
    }

    @Override
    protected Boolean validateThirdPartyStateFieldPathExpression(StateFieldPathExpression expression) {

        Boolean valid = null;

        // Retrieve the identification variable
        String variableName = literal(expression.getIdentificationVariable(), LiteralType.IDENTIFICATION_VARIABLE);

        if (variableName != ExpressionTools.EMPTY_STRING) {

            // Now find the associated declaration
            JPQLQueryDeclaration declaration = getDeclaration(variableName);

            if (declaration != null) {

                // The path expression is composed with an identification variable mapping a subquery
                if (declaration.getType() == JPQLQueryDeclaration.Type.SUBQUERY) {
                    valid = Boolean.TRUE;
                }
                else {
                    Expression baseExpression = declaration.getBaseExpression();

                    // If the base expression is a TableExpression, then we can
                    // continue to resolve the table and column names
                    if ((baseExpression != null) && isTableExpression(baseExpression)) {

                        // No need to validate if no extension was provided,
                        // but mark valid to true so it's not validated otherwise
                        if (extension == EclipseLinkSemanticValidatorExtension.NULL_EXTENSION) {
                            valid = Boolean.TRUE;
                        }
                        else {
                            valid = Boolean.FALSE;

                            // Retrieve the table name
                            String tableName = literal(baseExpression, LiteralType.STRING_LITERAL);

                            if (tableName != ExpressionTools.EMPTY_STRING) {
                                tableName = ExpressionTools.unquote(tableName);

                                // If the table name can be resolved, then validate the column name
                                if ((tableName != null) && extension.tableExists(tableName)) {
                                    String columnName = expression.getPath(1);

                                    // The column cannot be found on the table
                                    if (!extension.columnExists(tableName, columnName)) {
                                        addProblem(
                                            expression,
                                            StateFieldPathExpression_UnknownColumn,
                                            columnName,
                                            tableName
                                        );
                                    }
                                    else {
                                        valid = Boolean.TRUE;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        return valid;
    }

    @Override
    protected PathType validPathExpressionTypeForStringExpression() {
        // Loosen up the JPA spec restriction because ANTLR parser used to allow it
        return PathType.ANY_FIELD_INCLUDING_COLLECTION;
    }

    @Override
    public void visit(AsOfClause expression) {
        super.visit(expression);
        // Nothing to validate semantically
    }

    @Override
    public void visit(CastExpression expression) {
        super.visit(expression);
        // Nothing to validate semantically
    }

    @Override
    public void visit(ConnectByClause expression) {
        super.visit(expression);
        // Nothing to validate semantically
    }

    @Override
    public void visit(DatabaseType expression) {
        super.visit(expression);
        // Nothing to validate semantically
    }

    @Override
    public void visit(ExtractExpression expression) {
        super.visit(expression);
        // Nothing to validate semantically
    }

    @Override
    public void visit(HierarchicalQueryClause expression) {
        super.visit(expression);
        // Nothing to validate semantically
    }

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

    @Override
    public void visit(RegexpExpression expression) {
        super.visit(expression);
        // Nothing to validate semantically
    }

    @Override
    public void visit(StartWithClause expression) {
        super.visit(expression);
        // Nothing to validate semantically
    }

    @Override
    public void visit(TableExpression expression) {
        super.visit(expression);

        // No need to validate if no extension was defined
        if (extension != EclipseLinkSemanticValidatorExtension.NULL_EXTENSION) {
            Expression tableNameExpression = expression.getExpression();
            String tableName = literal(tableNameExpression, LiteralType.STRING_LITERAL);

            if (tableName != ExpressionTools.EMPTY_STRING) {
                tableName = ExpressionTools.unquote(tableName);

                if ((tableName.length() > 0) && !extension.tableExists(tableName)) {
                    addProblem(tableNameExpression, JPQLQueryProblemMessages.TableExpression_InvalidTableName);
                }
            }
        }
    }

    @Override
    public void visit(TableVariableDeclaration expression) {
        super.visit(expression);
        // Nothing to validate semantically
    }

    @Override
    public void visit(UnionClause expression) {
        super.visit(expression);
        // Nothing to validate semantically
    }

    // Made static final for performance reasons.
    /**
     * This visitor retrieves the clause owning the visited {@link Expression}.
     */
    public static final class EclipseLinkOwningClauseVisitor extends OwningClauseVisitor {

        public UnionClause unionClause;

        /**
         * Creates a new <code>EclipseLinkOwningClauseVisitor</code>.
         */
        public EclipseLinkOwningClauseVisitor() {
            super();
        }

        @Override
        public void dispose() {
            super.dispose();
            unionClause = null;
        }

        public void visit(UnionClause expression) {
            this.unionClause = expression;
        }
    }

    // Made static final for performance reasons.
    protected static final class SubquerySelectItemCalculator extends AnonymousExpressionVisitor {

        public int count;

        @Override
        public void visit(BadExpression expression) {
            count = 0;
        }

        @Override
        public void visit(CollectionExpression expression) {
            count = expression.childrenSize();
        }

        @Override
        protected void visit(Expression expression) {
            count = 1;
        }

        @Override
        public void visit(NullExpression expression) {
            count = 0;
        }

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

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

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

        /**
         * The {@link Expression} being visited.
         */
        protected Expression expression;

        /**
         * <code>true</code> if the {@link Expression} being visited is a {@link TableExpression}.
         */
        protected boolean valid;

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

    // Made static final for performance reasons.
    protected static final class TopLevelFirstDeclarationVisitor extends AbstractSemanticValidator.TopLevelFirstDeclarationVisitor {

        private final AbstractEclipseLinkSemanticValidator validator;

        private TopLevelFirstDeclarationVisitor(AbstractEclipseLinkSemanticValidator validator) {
            this.validator = validator;
        }

        @Override
        public void visit(CollectionValuedPathExpression expression) {

            // Derived path is not allowed, this could although be a fully
            // qualified class name, which was added to EclipseLink 2.4
            EclipseLinkVersion version = EclipseLinkVersion.value(validator.getProviderVersion());
            valid = version.isNewerThanOrEqual(EclipseLinkVersion.VERSION_2_4);

            if (valid) {
                Object type = validator.helper.getType(expression.toActualText());
                valid = validator.helper.isTypeResolvable(type);
            }
        }
    }
}
