/*
 * 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.parser;

import org.eclipse.persistence.jpa.jpql.EclipseLinkVersion;
import org.eclipse.persistence.jpa.jpql.JPAVersion;
import org.eclipse.persistence.jpa.jpql.parser.FunctionExpressionFactory.ParameterCount;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.*;

/**
 * <p>This {@link JPQLGrammar} provides support for parsing JPQL queries defined in <a
 * href="http://jcp.org/en/jsr/detail?id=317">JSR-338 - Java Persistence 2.1</a> and the additional
 * support provided by EclipseLink 2.4.</p>
 *
 * The BNFs of the additional support are the following:
 *
 * <pre><code> select_statement ::= select_clause from_clause [where_clause] [groupby_clause] [having_clause] [orderby_clause] {union_clause}*
 *
 * union_clause ::= { UNION | INTERSECT | EXCEPT} [ALL] subquery
 *
 * from_clause ::= FROM identification_variable_declaration {, {identification_variable_declaration |
 *                                                              collection_member_declaration |
 *                                                              (subquery) |
 *                                                              table_variable_declaration }}*
 *
 * range_variable_declaration ::= root_object [AS] identification_variable
 *
 * root_object ::= abstract_schema_name | fully_qualified_class_name
 *
 * table_variable_declaration ::= table_expression [AS] identification_variable
 *
 * join ::= join_spec { abstract_schema_name | join_association_path_expression } [AS] identification_variable [join_condition]
 *
 * functions_returning_datetime ::= cast_expression |
 *                                  extract_expression |
 *                                  ...
 *
 * functions_returning_string ::= cast_expression |
 *                                extract_expression |
 *                                ...
 *
 * functions_returning_numeric ::= cast_expression |
 *                                 extract_expression |
 *                                 ...
 *
 * simple_cond_expression ::= regexp_expression |
 *                            ...
 *
 * function_expression ::= { FUNC | FUNCTION | OPERATOR | SQL | COLUMN } (string_literal {, function_arg}*)
 *
 * regexp_expression ::= string_expression REGEXP pattern_value
 *
 * extract_expression ::= EXTRACT(date_part_literal [FROM] scalar_expression)
 *
 * table_expression ::= TABLE(string_literal)
 *
 * date_part_literal ::= { MICROSECOND | SECOND | MINUTE | HOUR | DAY | WEEK | MONTH | QUARTER |
 *                         YEAR | SECOND_MICROSECOND | MINUTE_MICROSECOND | MINUTE_SECOND |
 *                         HOUR_MICROSECOND | HOUR_SECOND | HOUR_MINUTE | DAY_MICROSECOND |
 *                         DAY_SECOND | DAY_MINUTE | DAY_HOUR | YEAR_MONTH, etc }
 *
 * cast_expression ::= CAST(scalar_expression [AS] database_type)
 *
 * database_type ::= data_type_literal [( [numeric_literal [, numeric_literal]] )]
 *
 * data_type_literal ::= [CHAR, VARCHAR, NUMERIC, INTEGER, DATE, TIME, TIMESTAMP, etc]</code></pre>
 *
 * <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.</p>
 *
 * @version 2.5
 * @since 2.4
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public final class EclipseLinkJPQLGrammar2_4 extends AbstractJPQLGrammar {

    /**
     * The singleton instance of this {@link EclipseLinkJPQLGrammar2_4}.
     */
    private static final JPQLGrammar INSTANCE = new EclipseLinkJPQLGrammar2_4();

    /**
     * The EclipseLink version, which is 2.4.
     */
    public static final EclipseLinkVersion VERSION = EclipseLinkVersion.VERSION_2_4;

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

    /**
     * Creates a new <code>EclipseLinkJPQLGrammar2_4</code>.
     *
     * @param jpqlGrammar The {@link JPQLGrammar} to extend with the content of this one without
     * instantiating the base {@link JPQLGrammar}
     */
    private EclipseLinkJPQLGrammar2_4(AbstractJPQLGrammar jpqlGrammar) {
        super(jpqlGrammar);
    }

    /**
     * Extends the given {@link JPQLGrammar} with the information of this one without instantiating
     * the base {@link JPQLGrammar}.
     *
     * @param jpqlGrammar The {@link JPQLGrammar} to extend with the content of this one without
     * instantiating the base {@link JPQLGrammar}
     */
    public static void extend(AbstractJPQLGrammar jpqlGrammar) {
        new EclipseLinkJPQLGrammar2_4(jpqlGrammar);
    }

    /**
     * Returns the singleton instance of this class.
     *
     * @return The singleton instance of {@link EclipseLinkJPQLGrammar2_4}
     */
    public static JPQLGrammar instance() {
        return INSTANCE;
    }

    @Override
    protected JPQLGrammar buildBaseGrammar() {

        // First build the JPQL 2.1 grammar
        JPQLGrammar2_1 jpqlGrammar = new JPQLGrammar2_1();

        // Extend it by adding the EclipseLink 2.0 additional support
        EclipseLinkJPQLGrammar2_0.extend(jpqlGrammar);

        // Extend it by adding the EclipseLink 2.1 additional support
        EclipseLinkJPQLGrammar2_1.extend(jpqlGrammar);

        return jpqlGrammar;
    }

    @Override
    public JPAVersion getJPAVersion() {
        return JPAVersion.VERSION_2_1;
    }

    @Override
    public String getProvider() {
        return DefaultEclipseLinkJPQLGrammar.PROVIDER_NAME;
    }

    @Override
    public String getProviderVersion() {
        return VERSION.getVersion();
    }

    @Override
    protected void initializeBNFs() {

        registerBNF(new CastExpressionBNF());
        registerBNF(new DatabaseTypeQueryBNF());
        registerBNF(new ExtractExpressionBNF());
        registerBNF(new InternalColumnExpressionBNF());
        registerBNF(new RegexpExpressionBNF());
        registerBNF(new TableExpressionBNF());
        registerBNF(new TableVariableDeclarationBNF());
        registerBNF(new UnionClauseBNF());

        // This is required to properly validate an entity name used as a join association path
        addChildBNF(JoinAssociationPathExpressionBNF.ID, AbstractSchemaNameBNF.ID);

        // Override (internal) simple_select_expression to add support for result variable
        registerBNF(new SimpleResultVariableBNF());

        // Note: This should only support SQL expression
        addChildBNF(SimpleConditionalExpressionBNF.ID,   FunctionExpressionBNF.ID);

        // CAST
        addChildBNF(FunctionsReturningDatetimeBNF.ID,    CastExpressionBNF.ID);
        addChildBNF(FunctionsReturningNumericsBNF.ID,    CastExpressionBNF.ID);
        addChildBNF(FunctionsReturningStringsBNF.ID,     CastExpressionBNF.ID);

        // EXTRACT
        addChildBNF(FunctionsReturningDatetimeBNF.ID,    ExtractExpressionBNF.ID);
        addChildBNF(FunctionsReturningNumericsBNF.ID,    ExtractExpressionBNF.ID);
        addChildBNF(FunctionsReturningStringsBNF.ID,     ExtractExpressionBNF.ID);

        // REGEXP
        addChildBNF(SimpleConditionalExpressionBNF.ID,   RegexpExpressionBNF.ID);

        // Add subquery support to RangeDeclarationBNF
        addChildBNF(RangeDeclarationBNF.ID,              SubqueryBNF.ID);

        // Add table declaration to the FROM clause's declaration
        addChildBNF(InternalFromClauseBNF.ID,            TableVariableDeclarationBNF.ID);
        addChildBNF(InternalSimpleFromClauseBNF.ID,      TableVariableDeclarationBNF.ID);

        // Trickle down the handling of a sub expression (subquery) to RangeVariableDeclaration
        // and in order to keep the hierarchy intact, otherwise the default behavior would be
        // FromClause would parse the subquery immediately.
        //
        // FromClause
        //  |- IdentificationVariableDeclaration
        //      |- RangeVariableDeclaration [(subquery) AS identification_variable]
        //          |- SubExpression
        //              |- SimpleSelectStatement
        setHandleSubExpression(InternalFromClauseBNF.ID,                true);
        setHandleSubExpression(InternalSimpleFromClauseBNF.ID,          true);
        setHandleSubExpression(IdentificationVariableDeclarationBNF.ID, true);
        setHandleSubExpression(RangeVariableDeclarationBNF.ID,          true);
    }

    @Override
    protected void initializeExpressionFactories() {

        registerFactory(new CastExpressionFactory());
        registerFactory(new DatabaseTypeFactory());
        registerFactory(new ExtractExpressionFactory());
        registerFactory(new JoinCollectionValuedPathExpressionFactory());
        registerFactory(new OnClauseFactory());
        registerFactory(new RegexpExpressionFactory());
        registerFactory(new TableExpressionFactory());
        registerFactory(new TableVariableDeclarationFactory());
        registerFactory(new UnionClauseFactory());

        // Add a new FunctionExpression for 'COLUMN' since it has different rules
        FunctionExpressionFactory columnExpressionFactory = new FunctionExpressionFactory(COLUMN, COLUMN);
        columnExpressionFactory.setParameterCount(ParameterCount.ONE);
        columnExpressionFactory.setParameterQueryBNFId(InternalColumnExpressionBNF.ID);
        registerFactory(columnExpressionFactory);

        // Add COLUMN ExpressionFactory to FunctionExpressionBNF
        addChildFactory(FunctionExpressionBNF.ID, COLUMN);

        // Change the fallback ExpressionFactory to add support for an abstract schema name
        // as a valid join association path expression
        setFallbackExpressionFactoryId(JoinAssociationPathExpressionBNF.ID, JoinCollectionValuedPathExpressionFactory.ID);
    }

    @Override
    protected void initializeIdentifiers() {

        // Expand FunctionExpression to support 'FUNCTION', 'OPERATOR' and 'SQL'
        addIdentifiers(FunctionExpressionFactory.ID, FUNCTION, OPERATOR, SQL);

        registerIdentifierRole(CAST,           IdentifierRole.FUNCTION);          // FUNCTION(n, x1, ..., x2)
        registerIdentifierRole(COLUMN,         IdentifierRole.FUNCTION);          // FUNCTION(n, x1, ..., x2)
        registerIdentifierRole(EXCEPT,         IdentifierRole.CLAUSE);
        registerIdentifierRole(EXTRACT,        IdentifierRole.FUNCTION);          // EXTRACT(x FROM y)
        registerIdentifierRole(FUNCTION,       IdentifierRole.FUNCTION);          // FUNCTION(n, x1, ..., x2)
        registerIdentifierRole(INTERSECT,      IdentifierRole.CLAUSE);
        registerIdentifierRole(NULLS_FIRST,    IdentifierRole.COMPLEMENT);
        registerIdentifierRole(NULLS_LAST,     IdentifierRole.COMPLEMENT);
        registerIdentifierRole(ON,             IdentifierRole.CLAUSE);            // ON x
        registerIdentifierRole(OPERATOR,       IdentifierRole.FUNCTION);          // FUNCTION(n, x1, ..., x2)
        registerIdentifierRole(REGEXP,         IdentifierRole.COMPOUND_FUNCTION); // x REGEXP y
        registerIdentifierRole(SQL,            IdentifierRole.FUNCTION);          // FUNCTION(n, x1, ..., x2)
        registerIdentifierRole(TABLE,          IdentifierRole.FUNCTION);          // TABLE('TABLE_NAME')
        registerIdentifierRole(UNION,          IdentifierRole.CLAUSE);

        registerIdentifierVersion(CAST,        JPAVersion.VERSION_2_1);
        registerIdentifierVersion(COLUMN,      JPAVersion.VERSION_2_1);
        registerIdentifierVersion(EXCEPT,      JPAVersion.VERSION_2_1);
        registerIdentifierVersion(EXTRACT,     JPAVersion.VERSION_2_1);
        registerIdentifierVersion(FUNCTION,    JPAVersion.VERSION_2_1);
        registerIdentifierVersion(INTERSECT,   JPAVersion.VERSION_2_1);
        registerIdentifierVersion(NULLS_FIRST, JPAVersion.VERSION_2_1);
        registerIdentifierVersion(NULLS_LAST,  JPAVersion.VERSION_2_1);
        registerIdentifierVersion(ON,          JPAVersion.VERSION_2_1);
        registerIdentifierVersion(OPERATOR,    JPAVersion.VERSION_2_1);
        registerIdentifierVersion(REGEXP,      JPAVersion.VERSION_2_1);
        registerIdentifierVersion(SQL,         JPAVersion.VERSION_2_1);
        registerIdentifierVersion(TABLE,       JPAVersion.VERSION_2_1);
        registerIdentifierVersion(UNION,       JPAVersion.VERSION_2_1);

        // Partial identifiers
        registerIdentifierRole("NULLS",        IdentifierRole.CLAUSE);       // Part of NULLS FIRST, NULLS LAST
        registerIdentifierRole("FIRST",        IdentifierRole.CLAUSE);       // Part of NULLS FIRST
        registerIdentifierRole("LAST",         IdentifierRole.CLAUSE);       // Part of NULLS LAST
    }

    @Override
    public String toString() {
        return "EclipseLink 2.4";
    }
}
