/*
 * Copyright (c) 2012, 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.Assert;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.WordParser;

/**
 * This {@link FunctionExpressionFactory} creates a new {@link FunctionExpression} when the portion
 * of the query to parse starts with an identifier related to a SQL function.
 *
 * @see FunctionExpression
 *
 * @version 2.5
 * @since 2.4
 * @author James
 */
@SuppressWarnings("nls")
public final class FunctionExpressionFactory extends ExpressionFactory {

    /**
     * The number of {@link ParameterCount parameters} a {@link FunctionExpression} can have.
     */
    private ParameterCount parameterCount;

    /**
     * The unique identifier of the {@link JPQLQueryBNF} that will be used to parse the arguments of
     * the function expression.
     */
    private String parameterQueryBNFId;

    /**
     * The unique identifier for this {@link FunctionExpressionFactory}.
     */
    public static final String ID = Expression.FUNCTION;

    /**
     * Creates a new <code>FunctionExpressionFactory</code>.
     *
     * @param id The unique identifier of this factory
     * @param parameterCount The number of {@link ParameterCount parameters} a {@link
     * FunctionExpression} can have
     * @param parameterQueryBNFId The unique identifier of the {@link JPQLQueryBNF} that will be used
     * to parse the arguments of the function expression
     * @param identifiers The JPQL identifiers handled by this factory
     */
    public FunctionExpressionFactory(String id,
                                     ParameterCount parameterCount,
                                     String parameterQueryBNFId,
                                     String... identifiers) {

        super(id, identifiers);
        setParameterCount(parameterCount);
        setParameterQueryBNFId(parameterQueryBNFId);
    }

    /**
     * Creates a new <code>FunctionExpressionFactory</code>.
     *
     * @param id The unique identifier of this factory
     * @param identifiers The JPQL identifiers handled by this factory
     */
    public FunctionExpressionFactory(String id, String... identifiers) {
        this(id, ParameterCount.ZERO_OR_MANY, FunctionItemBNF.ID, identifiers);
    }

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

        // Search for the constant that is registered with this factory
        String identifier = null;

        for (String possibleIdentifier : identifiers()) {
            if (possibleIdentifier.equalsIgnoreCase(word)) {
                identifier = possibleIdentifier;
                break;
            }
        }

        // No constant was found
        if (identifier == null) {
            return null;
        }

        // Make sure the new function is a real expression and not a variable name.
        // Example: SELECT column FROM Column column
        if (ExpressionTools.isFunctionExpression(wordParser, identifier)) {
            expression = new FunctionExpression(parent, identifier, parameterCount, parameterQueryBNFId);
            expression.parse(wordParser, tolerant);
            return expression;
        }

        return null;
    }

    /**
     * Sets the number of parameters a {@link FunctionExpression} can have, which will be during
     * validation.
     *
     * @param parameterCount The number of parameters
     */
    public void setParameterCount(ParameterCount parameterCount) {
        Assert.isNotNull(parameterCount, "The ParameterCount cannot be null");
        this.parameterCount = parameterCount;
    }

    /**
     * Sets the BNF that will be used when parsing the function's arguments.
     *
     * @param parameterQueryBNFId The unique identifier of the {@link JPQLQueryBNF} that will be used
     * to parse the arguments of the function expression
     */
    public void setParameterQueryBNFId(String parameterQueryBNFId) {
        Assert.isNotNull(parameterQueryBNFId, "The JPQLQueryBNF for the parameters cannot be null");
        this.parameterQueryBNFId = parameterQueryBNFId;
    }

    /**
     * The number of parameters a {@link FunctionExpression} can have.
     */
    public enum ParameterCount {

        /**
         * Only one parameter is allowed.
         */
        ONE,

        /**
         * [1, n] are allowed.
         */
        ONE_OR_MANY,

        /**
         * No parameters are allowed.
         */
        ZERO,

        /**
         * [0, n] are allowed.
         */
        ZERO_OR_MANY,

        /**
         * [0, 1] are allowed.
         */
        ZERO_OR_ONE
    }
}
