/*
 * Copyright (c) 2006, 2019 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);
    }

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

    /**
     * {@inheritDoc}
     */
    @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();
    }

    /**
     * {@inheritDoc}
     */
    @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());
    }

    /**
     * {@inheritDoc}
     */
    @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);
        }

        /**
         * {@inheritDoc}
         */
        @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);
        }

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

        /**
         * {@inheritDoc}
         */
        @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));
        }

        /**
         * {@inheritDoc}
         */
        @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);
        }
    }
}
