/*
 * Copyright (c) 2011, 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.tools.model;

import org.eclipse.persistence.jpa.jpql.parser.*;
import org.eclipse.persistence.jpa.jpql.tools.model.query.JPQLQueryStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.StateObject;
import org.eclipse.persistence.jpa.jpql.tools.spi.IManagedTypeProvider;

/**
 * An abstract implementation of {@link IJPQLQueryBuilder} that parses a JPQL query or any JPQL
 * fragments and creates the {@link StateObject} representation by delegating the creation to an
 * instance of {@link BasicStateObjectBuilder}.
 *
 * @see DefaultJPQLQueryBuilder
 * @see EclipseLinkJPQLQueryBuilder
 *
 * @version 2.4
 * @since 2.4
 * @author Pascal Filion
 */
public abstract class AbstractJPQLQueryBuilder implements IJPQLQueryBuilder {

    /**
     * Keeps a reference for future use.
     */
    private BasicStateObjectBuilder builder;

    /**
     * Creates a new <code>AbstractJPQLQueryBuilder</code>.
     */
    protected AbstractJPQLQueryBuilder() {
        super();
    }

    @Override
    public ICaseExpressionStateObjectBuilder buildCaseExpressionStateObjectBuilder(StateObject parent) {
        return new DefaultCaseExpressionStateObjectBuilder(parent);
    }

    @Override
    public JPQLQueryStateObject buildStateObject(IManagedTypeProvider provider,
                                                 CharSequence jpqlQuery,
                                                 boolean tolerant) {

        return buildStateObject(provider, jpqlQuery, JPQLStatementBNF.ID, tolerant);
    }

    @Override
    public JPQLQueryStateObject buildStateObject(IManagedTypeProvider provider,
                                                 CharSequence jpqlQuery,
                                                 String queryBNFId,
                                                 boolean tolerant) {

        // First parse the JPQL query
        JPQLExpression jpqlExpression = parse(jpqlQuery, getGrammar(), tolerant);

        // Now visit the parsed expression and create the state object hierarchy
        BasicStateObjectBuilder builder = getStateObjectBuilder();

        try {
            builder.jpqlQueryBuilder    = this;
            builder.managedTypeProvider = provider;

            jpqlExpression.accept(wrap(builder));

            return builder.parent;
        }
        finally {
            builder.jpqlQueryBuilder    = null;
            builder.managedTypeProvider = null;
            builder.parent              = null;
            builder.stateObject         = null;
        }
    }

    @Override
    public StateObject buildStateObject(StateObject parent,
                                        CharSequence jpqlFragment,
                                        String queryBNFId) {

        // First parse the JPQL fragment
        JPQLExpression jpqlExpression = parse(jpqlFragment, parent.getGrammar(), queryBNFId);

        // We keep track of the old stuff because during the creation of a JPQLQueryStateObject,
        // it is possible the state model uses this builder to create some objects
        BasicStateObjectBuilder builder  = getStateObjectBuilder();
        IJPQLQueryBuilder oldBuilder     = builder.jpqlQueryBuilder;
        IManagedTypeProvider oldProvider = builder.managedTypeProvider;
        JPQLQueryStateObject oldParent   = builder.parent;
        StateObject oldStateObject       = builder.stateObject;

        try {
            builder.jpqlQueryBuilder    = this;
            builder.managedTypeProvider = parent.getManagedTypeProvider();
            builder.parent              = parent.getRoot();
            builder.stateObject         = parent;

            // Visit the Expression for which a StateObject is needed
            jpqlExpression.getQueryStatement().accept(wrap(builder));

            return builder.stateObject;
        }
        finally {
            builder.jpqlQueryBuilder    = oldBuilder;
            builder.managedTypeProvider = oldProvider;
            builder.parent              = oldParent;
            builder.stateObject         = oldStateObject;
        }
    }

    /**
     * Creates the builder that creates the {@link StateObject} for each {@link org.eclipse.persistence.jpa.jpql.parser.Expression Expression}.
     *
     * @return The builder that will be visiting the {@link org.eclipse.persistence.jpa.jpql.parser.Expression Expression}
     */
    protected abstract BasicStateObjectBuilder buildStateObjectBuilder();

    /**
     * Returns the builder that creates the {@link StateObject} for each {@link org.eclipse.persistence.jpa.jpql.parser.Expression Expression}.
     *
     * @return The builder that will be visiting the {@link org.eclipse.persistence.jpa.jpql.parser.Expression Expression}
     */
    protected final BasicStateObjectBuilder getStateObjectBuilder() {
        if (builder == null) {
            builder = buildStateObjectBuilder();
        }
        return builder;
    }

    /**
     * Parses the given JPQL query with tolerant mode turned on.
     *
     * @param jpqlQuery The string representation of the JPQL query to parse
     * @param jpqlGrammar The JPQL grammar that defines how to parse a JPQL query
     * @param tolerant Determines if the parsing system should be tolerant, meaning if it should try
     * to parse invalid or incomplete queries
     * @return The root of the parsed tree representation of the JPQL query
     */
    protected JPQLExpression parse(CharSequence jpqlQuery, JPQLGrammar jpqlGrammar, boolean tolerant) {
        return new JPQLExpression(jpqlQuery, jpqlGrammar, tolerant);
    }

    /**
     * Parses the given JPQL fragment with tolerant mode turned on.
     *
     * @param jpqFragment The string representation of the portion of a JPQL query to parse
     * @param jpqlGrammar The JPQL grammar that defines how to parse a JPQL query
     * @param queryBNFId The unique identifier of the {@link JPQLQueryBNF}
     * @return The root of the parsed tree representation of the JPQL fragment
     */
    protected JPQLExpression parse(CharSequence jpqFragment,
                                   JPQLGrammar jpqlGrammar,
                                   String queryBNFId) {

        return new JPQLExpression(jpqFragment, jpqlGrammar, queryBNFId, true);
    }

    /**
     * If a subclass needs to wrap the given {@link BasicStateObjectBuilder} with another visitor can
     * do so by simply overriding this method. {@link #buildStateObjectBuilder()} can't be easily
     * overridden with an {@link ExpressionVisitor} due to the constraint on the return type.
     *
     * @param builder The builder to wrap
     * @return By default the given builder is returned
     */
    protected ExpressionVisitor wrap(BasicStateObjectBuilder builder) {
        return builder;
    }
}
