/*
 * 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.internal.jpa.jpql;

import java.text.MessageFormat;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Map;
import java.util.ResourceBundle;
import org.eclipse.persistence.config.ParserValidationType;
import org.eclipse.persistence.exceptions.JPQLException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.internal.expressions.ParameterExpression;
import org.eclipse.persistence.internal.queries.JPQLCallQueryMechanism;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.jpa.jpql.EclipseLinkGrammarValidator;
import org.eclipse.persistence.jpa.jpql.JPQLQueryProblem;
import org.eclipse.persistence.jpa.jpql.JPQLQueryProblemResourceBundle;
import org.eclipse.persistence.jpa.jpql.parser.AbstractExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.ConditionalExpressionBNF;
import org.eclipse.persistence.jpa.jpql.parser.DefaultEclipseLinkJPQLGrammar;
import org.eclipse.persistence.jpa.jpql.parser.DeleteStatement;
import org.eclipse.persistence.jpa.jpql.parser.InputParameter;
import org.eclipse.persistence.jpa.jpql.parser.JPQLExpression;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar1_0;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar2_0;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar2_1;
import org.eclipse.persistence.jpa.jpql.parser.SelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.UpdateStatement;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.DatabaseQuery.ParameterType;
import org.eclipse.persistence.queries.DeleteAllQuery;
import org.eclipse.persistence.queries.JPAQueryBuilder;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.queries.ReportQuery;
import org.eclipse.persistence.queries.UpdateAllQuery;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.*;

/**
 * This class compiles a JPQL query into a {@link DatabaseQuery}. If validation is not turned off,
 * then the JPQL query will be validated based on the grammar related to the validation level and
 * will also be validated based on the semantic (context).
 * <p>
 * The validation level determines how to validate the JPQL query. It checks if any specific feature
 * is allowed. For instance, if the JPQL query has functions defined for EclipseLink grammar but
 * the validation level is set for generic JPA, then an exception will be thrown indicating the
 * function cannot be used.
 *
 * @see JPQLExpression
 *
 * @version 2.5
 * @since 2.3
 * @author John Bracken
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public final class HermesParser implements JPAQueryBuilder {

    /**
     * Determines how to validate the JPQL query grammatically.
     */
    private String validationLevel;

    /**
     * Creates a new <code>HermesParser</code>.
     */
    public HermesParser() {
        super();
        validationLevel = ParserValidationType.DEFAULT;
    }

    /**
     * Registers the input parameters derived from the JPQL expression with the {@link DatabaseQuery}.
     *
     * @param queryContext The {@link JPQLQueryContext} containing the information about the JPQL query
     * @param databaseQuery The EclipseLink {@link DatabaseQuery} where the input parameter types are added
     */
    private void addArguments(JPQLQueryContext queryContext, DatabaseQuery databaseQuery) {

        if (queryContext.inputParameters != null) {

            for (Map.Entry<InputParameter, Expression> entry : queryContext.inputParameters.entrySet()) {
                ParameterExpression parameter = (ParameterExpression) entry.getValue();

                databaseQuery.addArgument(
                    parameter.getField().getName(),
                    (Class<?>) parameter.getType(),
                    entry.getKey().isPositional() ? ParameterType.POSITIONAL : ParameterType.NAMED
                );
            }
        }
    }

    /**
     * Creates a {@link JPQLException} indicating the problems with the JPQL query.
     *
     * @param queryContext The {@link JPQLQueryContext} containing the information about the JPQL query
     * @param problems The {@link JPQLQueryProblem problems} found in the JPQL query that are
     * translated into an exception
     * @param messageKey The key used to retrieve the localized message
     * @return The {@link JPQLException} indicating the problems with the JPQL query
     */
    private JPQLException buildException(JPQLQueryContext queryContext,
                                         Collection<JPQLQueryProblem> problems,
                                         String messageKey) {

        ResourceBundle bundle = resourceBundle();
        StringBuilder sb = new StringBuilder();

        for (JPQLQueryProblem problem : problems) {

            // Retrieve the localized message
            String message;

            try {
                message = bundle.getString(problem.getMessageKey());
            }
            catch (NullPointerException e) {
                // In case the resource bundle was not updated
                message = problem.getMessageKey();
            }

            // Now format the localized message
            String[] arguments = problem.getMessageArguments();

            if (arguments.length > 0) {
                message = MessageFormat.format(message, (Object[]) arguments);
            }

            // Append the description
            sb.append("\n");
            sb.append("[");
            sb.append(problem.getStartPosition());
            sb.append(", ");
            sb.append(problem.getEndPosition());
            sb.append("] ");
            sb.append(message);
        }

        String errorMessage = bundle.getString(messageKey);
        errorMessage = MessageFormat.format(errorMessage, queryContext.getJPQLQuery(), sb);
        return new JPQLException(errorMessage);
    }

    @Override
    public DatabaseQuery buildQuery(CharSequence jpqlQuery, AbstractSession session) {
        return populateQueryImp(jpqlQuery, null, session);
    }

    @Override
    public Expression buildSelectionCriteria(String entityName,
                                             String selectionCriteria,
                                             AbstractSession session) {

        try {
            // Create the parsed tree representation of the selection criteria
            JPQLExpression jpqlExpression = new JPQLExpression(
                selectionCriteria,
                DefaultEclipseLinkJPQLGrammar.instance(),
                ConditionalExpressionBNF.ID,
                isTolerant()
            );

            // Caches the info and add a virtual range variable declaration
            JPQLQueryContext queryContext = new JPQLQueryContext(jpqlGrammar());
            queryContext.cache(session, null, jpqlExpression, selectionCriteria);
            queryContext.addRangeVariableDeclaration(entityName, "this");

            // Validate the JPQL query, which will use the JPQL grammar matching the validation
            // level, for now, only validate the query statement because there could be an unknown
            // ending that is an order by clause
            validate(queryContext, jpqlExpression.getQueryStatement());

            // Create the Expression representing the selection criteria
            return queryContext.buildExpression(jpqlExpression.getQueryStatement());
        }
        catch (JPQLException exception) {
            throw exception;
        }
        catch (Exception exception) {
            throw buildUnexpectedException(selectionCriteria, exception);
        }
    }

    private JPQLException buildUnexpectedException(CharSequence jpqlQuery, Exception exception) {
        String errorMessage = resourceBundle().getString(HermesParser_UnexpectedException_ErrorMessage);
        errorMessage = MessageFormat.format(errorMessage, jpqlQuery);
        return new JPQLException(errorMessage, exception);
    }

    /**
     * Determines whether the JPQL query should be parsed with tolerance turned on or off, i.e. if
     * validation is turned off, then it's assumed the JPQL query is grammatically valid and complete.
     * In this case, it will be parsed with tolerance turned off resulting in better performance.
     *
     * @return <code>true</code> if the query might be incomplete or invalid; <code>false</code> if
     * the query is complete and grammatically valid
     */
    private boolean isTolerant() {
        return validationLevel != ParserValidationType.None;
    }

    /**
     * Returns the {@link JPQLGrammar} that will help to validate the JPQL query grammatically and
     * semantically (contextually). It will also checks if any specific feature added to that grammar
     * is allowed. For instance, if the JPQL query has functions defined for EclipseLink grammar but
     * the validation level is set for generic JPA, then an exception will be thrown.
     *
     * @return The {@link JPQLGrammar} written for a specific JPA version or for the current version
     * of EclipseLink
     */
    private JPQLGrammar jpqlGrammar() {

        if (validationLevel == ParserValidationType.EclipseLink) {
            return DefaultEclipseLinkJPQLGrammar.instance();
        }

        if (validationLevel == ParserValidationType.JPA10) {
            return JPQLGrammar1_0.instance();
        }

        if (validationLevel == ParserValidationType.JPA20) {
            return JPQLGrammar2_0.instance();
        }

        if (validationLevel == ParserValidationType.JPA21) {
            return JPQLGrammar2_1.instance();
        }

        return DefaultEclipseLinkJPQLGrammar.instance();
    }

    @Override
    public void populateQuery(CharSequence jpqlQuery, DatabaseQuery query, AbstractSession session) {
        populateQueryImp(jpqlQuery, query, session);
    }

    private DatabaseQuery populateQueryImp(CharSequence jpqlQuery,
                                           DatabaseQuery query,
                                           AbstractSession session) {

        try {
            // Parse the JPQL query with the most recent JPQL grammar
            JPQLExpression jpqlExpression = new JPQLExpression(
                jpqlQuery,
                DefaultEclipseLinkJPQLGrammar.instance(),
                isTolerant()
            );

            // Create a context that caches the information contained in the JPQL query
            // (especially from the FROM clause)
            JPQLQueryContext queryContext = new JPQLQueryContext(jpqlGrammar());
            queryContext.cache(session, query, jpqlExpression, jpqlQuery);

            // Validate the JPQL query, which will use the JPQL grammar matching the validation level
            validate(queryContext, jpqlExpression);

            // Create the DatabaseQuery by visiting the parsed tree
            DatabaseQueryVisitor visitor = new DatabaseQueryVisitor(queryContext, jpqlQuery);
            jpqlExpression.accept(visitor);

            // Add the input parameter types to the DatabaseQuery
            if (query == null) {
                query = queryContext.getDatabaseQuery();
                addArguments(queryContext, query);
            }

            return query;
        }
        catch (JPQLException exception) {
            throw exception;
        }
        catch (Exception exception) {
            throw buildUnexpectedException(jpqlQuery, exception);
        }
    }

    private ResourceBundle resourceBundle() {
        return ResourceBundle.getBundle(JPQLQueryProblemResourceBundle.class.getName());
    }

    @Override
    public void setValidationLevel(String validationLevel) {
        this.validationLevel = validationLevel;
    }

    /**
     * Grammatically and semantically validates the JPQL query. If the query is not valid, then an
     * exception will be thrown.
     *
     * @param queryContext The context used to query information about the application metadata and
     * cached information
     * @param expression The {@link org.eclipse.persistence.jpa.jpql.parser.Expression Expression} to
     * validate grammatically and semantically
     */
    private void validate(JPQLQueryContext queryContext,
                          org.eclipse.persistence.jpa.jpql.parser.Expression expression) {

        if (validationLevel != ParserValidationType.None) {

            Collection<JPQLQueryProblem> problems = new LinkedList<>();

            // Validate the JPQL query grammatically (based on the JPQL grammar)
            EclipseLinkGrammarValidator grammar = new EclipseLinkGrammarValidator(jpqlGrammar());
            grammar.setProblems(problems);
            expression.accept(grammar);

            if (!problems.isEmpty()) {
                throw buildException(
                    queryContext,
                    problems,
                    HermesParser_GrammarValidator_ErrorMessage
                );
            }

            // Validate the JPQL query semantically (contextually)
            EclipseLinkSemanticValidator semantic = new EclipseLinkSemanticValidator(queryContext);
            semantic.setProblems(problems);
            expression.accept(semantic);

            if (!problems.isEmpty()) {
                throw buildException(
                    queryContext,
                    problems,
                    HermesParser_SemanticValidator_ErrorMessage
                );
            }
        }
    }

    /**
     * This visitor traverses the parsed tree and create the right EclipseLink query and populates it.
     */
    private static class DatabaseQueryVisitor extends AbstractExpressionVisitor {

        private final String jpqlQuery;
        private final JPQLQueryContext queryContext;

        DatabaseQueryVisitor(JPQLQueryContext queryContext, CharSequence jpqlQuery) {
            super();
            this.jpqlQuery = jpqlQuery.toString();
            this.queryContext = queryContext;
        }

        private ReadAllQuery buildReadAllQuery(SelectStatement expression) {
            ReadAllQueryBuilder visitor = new ReadAllQueryBuilder(queryContext);
            expression.accept(visitor);
            return visitor.query;
        }

        private AbstractObjectLevelReadQueryVisitor buildVisitor(ObjectLevelReadQuery query) {

            if (query.isReportQuery()) {
                return new ReportQueryVisitor(queryContext, (ReportQuery) query);
            }

            if (query.isReadAllQuery()) {
                return new ReadAllQueryVisitor(queryContext, (ReadAllQuery) query);
            }

            return new ObjectLevelReadQueryVisitor(queryContext, query);
        }

        @Override
        public void visit(DeleteStatement expression) {

            DeleteAllQuery query = queryContext.getDatabaseQuery();

            // Create and prepare the query
            if (query == null) {
                query = new DeleteAllQuery();
                queryContext.setDatabasQuery(query);
                query.setJPQLString(jpqlQuery);
                ((JPQLCallQueryMechanism) query.getQueryMechanism()).getJPQLCall().setIsParsed(true);
            }

            query.setSession(queryContext.getSession());
            query.setShouldDeferExecutionInUOW(false);

            // Now populate it
            DeleteQueryVisitor visitor = new DeleteQueryVisitor(queryContext, query);
            expression.accept(visitor);
        }

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

        @Override
        public void visit(SelectStatement expression) {

            ObjectLevelReadQuery query = queryContext.getDatabaseQuery();

            // Create and prepare the query
            if (query == null) {
                query = buildReadAllQuery(expression);
                queryContext.setDatabasQuery(query);
                query.setJPQLString(jpqlQuery);
                ((JPQLCallQueryMechanism) query.getQueryMechanism()).getJPQLCall().setIsParsed(true);
            }

            // Now populate it
            expression.accept(buildVisitor(query));
        }

        @Override
        public void visit(UpdateStatement expression) {

            UpdateAllQuery query = queryContext.getDatabaseQuery();

            // Create and prepare the query
            if (query == null) {
                query = new UpdateAllQuery();
                queryContext.setDatabasQuery(query);
                query.setJPQLString(jpqlQuery);
                ((JPQLCallQueryMechanism) query.getQueryMechanism()).getJPQLCall().setIsParsed(true);
            }

            query.setSession(queryContext.getSession());
            query.setShouldDeferExecutionInUOW(false);

            // Now populate it
            UpdateQueryVisitor visitor = new UpdateQueryVisitor(queryContext, query);
            expression.accept(visitor);
        }
    }
}
