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

/**
 * This factory is responsible to return the right literal expression.
 *
 * @see StringLiteral
 * @see InputParameter
 * @see NumericLiteral
 * @see KeywordExpression
 * @see StateFieldPathExpression
 * @see IdentificationVariable
 *
 * @version 2.5
 * @since 2.3
 * @author Pascal Filion
 */
public abstract class AbstractLiteralExpressionFactory extends ExpressionFactory {

    /**
     * Creates a new <code>AbstractLiteralExpressionFactory</code>.
     *
     * @param id The unique identifier of this {@link ExpressionFactory}
     */
    protected AbstractLiteralExpressionFactory(String id) {
        super(id);
    }

    /**
     * Creates the actual {@link AbstractExpression} this factory manages.
     *
     * @param parent The parent {@link AbstractExpression}
     * @param wordParser The text to parse based on the current position of the cursor
     * @param word The current word being parsed
     * @param expression During the parsing, it is possible the first part of an expression was
     * parsed which needs to be used as a sub-expression of the newly created expression
     * @return A new {@link AbstractExpression} representing the portion or the totality of the
     * text held by {@link WordParser} starting at the cursor position
     */
    protected abstract AbstractExpression buildExpression(AbstractExpression parent,
                                                          WordParser wordParser,
                                                          String word,
                                                          AbstractExpression expression,
                                                          boolean tolerant);

    @Override
    protected AbstractExpression buildExpression(AbstractExpression parent,
                                                 WordParser wordParser,
                                                 String word,
                                                 JPQLQueryBNF queryBNF,
                                                 AbstractExpression expression,
                                                 boolean tolerant) {

        switch (wordParser.getWordType()) {

            case NUMERIC_LITERAL: {
                expression = new NumericLiteral(parent, word);
                expression.parse(wordParser, tolerant);
                return expression;
            }

            case STRING_LITERAL: {
                expression = new StringLiteral(parent, word);
                expression.parse(wordParser, tolerant);
                return expression;
            }

            case INPUT_PARAMETER: {
                expression = new InputParameter(parent, word);
                expression.parse(wordParser, tolerant);
                return expression;
            }
        }

        // Path expression
        if (word.indexOf(AbstractExpression.DOT) > -1) {
            char character = word.charAt(0);

            if ((expression != null) && (character == AbstractExpression.DOT)) {
                if (isCollection()) {
                    expression = new CollectionValuedPathExpression(parent, expression, word);
                }
                else {
                    expression = new StateFieldPathExpression(parent, expression, word);
                }
            }
            else {
                if (isCollection()) {
                    expression = new CollectionValuedPathExpression(parent, word);
                }
                else {
                    expression = new StateFieldPathExpression(parent, word);
                }
            }

            expression.parse(wordParser, tolerant);
            return expression;
        }

        // Checks for invalid JPQL queries
        ExpressionRegistry registry = getExpressionRegistry();

        if (tolerant && registry.isIdentifier(word)) {
            ExpressionFactory factory = registry.expressionFactoryForIdentifier(word);
            // TODO: Before creating the expression, check to make sure it's not a function: 'identifier('
            if (factory != null) {
                expression = factory.buildExpression(parent, wordParser, word, queryBNF, expression, tolerant);

                if (expression != null) {
                    return new BadExpression(parent, expression);
                }
            }
        }

        return buildExpression(parent, wordParser, word, expression, tolerant);
    }

    /**
     * Determines
     *
     * @return
     */
    protected boolean isCollection() {
        return false;
    }
}
