/*
 * Copyright (c) 2006, 2020 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 java.util.Arrays;
import org.eclipse.persistence.jpa.jpql.WordParser;

/**
 * An <code>ExpressionFactory</code> is responsible to parse a portion of JPQL query which starts
 * with one of the factory's JPQL identifiers.
 * <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.
 *
 * @version 2.5
 * @since 2.3
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public abstract class ExpressionFactory implements Comparable<ExpressionFactory> {

    /**
     * The {@link ExpressionRegistry} with which this {@link ExpressionFactory} was registered.
     */
    private ExpressionRegistry expressionRegistry;

    /**
     * The unique identifier of this {@link ExpressionFactory}.
     */
    private final String id;

    /**
     * The JPQL identifiers handled by this factory.
     */
    private String[] identifiers;

    /**
     * Creates a new <code>ExpressionFactory</code>.
     *
     * @param id The unique identifier of this <code>ExpressionFactory</code>
     * @param identifiers The JPQL identifiers handled by this factory
     * @exception NullPointerException The given unique identifier cannot be <code>null</code> or
     * the list of JPQL identifiers was <code>null</code>
     */
    protected ExpressionFactory(String id, String... identifiers) {
        super();
        this.id = id;
        this.identifiers = identifiers;
    }

    /**
     * Adds the given JPQL identifier to this factory.
     *
     * @param identifier The JPQL identifier this factory will parse
     */
    void addIdentifier(String identifier) {

        String[] newIdentifiers = new String[identifiers.length + 1];
        newIdentifiers[identifiers.length] = identifier;
        System.arraycopy(identifiers, 0, newIdentifiers, 0, identifiers.length);

        identifiers = newIdentifiers;
    }

    /**
     * Adds the given JPQL identifiers to this factory.
     *
     * @param identifier The JPQL identifiers this factory will parse
     */
    void addIdentifiers(String... identifiers) {

        int originalLength = this.identifiers.length;

        String[] newIdentifiers = new String[this.identifiers.length + identifiers.length];
        System.arraycopy(this.identifiers, 0, newIdentifiers, 0, this.identifiers.length);
        System.arraycopy(identifiers, 0, newIdentifiers, originalLength, identifiers.length);

        this.identifiers = newIdentifiers;
    }

    /**
     * Creates a new {@link Expression}.
     *
     * @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 queryBNF The BNF grammar that was used to identifier this factory to be capable to
     * parse a portion of the query
     * @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,
                                                          JPQLQueryBNF queryBNF,
                                                          AbstractExpression expression,
                                                          boolean tolerant);

    /**
     * {@inheritDoc}
     */
    @Override
    public final int compareTo(ExpressionFactory expressionFactory) {
        return id.compareTo(expressionFactory.getId());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final boolean equals(Object object) {
                if (object == null) {
                    return false;
                }
        if (this == object) {
            return true;
        }

        ExpressionFactory factory = (ExpressionFactory) object;
        return id.equals(factory.id);
    }

    /**
     * Returns the registry containing the {@link JPQLQueryBNF JPQLQueryBNFs} and the {@link
     * org.eclipse.persistence.jpa.jpql.parser.ExpressionFactory ExpressionFactories} that are used
     * to properly parse a JPQL query.
     *
     * @return The registry containing the information related to the JPQL grammar
     */
    public final ExpressionRegistry getExpressionRegistry() {
        return expressionRegistry;
    }

    /**
     * Returns the unique identifier of this <code>ExpressionFactory</code>.
     *
     * @return The identifier used to register this {@link ExpressionFactory} with {@link
     * ExpressionRegistry}
     */
    public final String getId() {
        return id;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final int hashCode() {
        return id.hashCode();
    }

    /**
     * Returns the JPQL identifiers handled by this factory.
     *
     * @return The list of JPQL identifiers this factory knows how to parse
     */
    public final String[] identifiers() {
        return identifiers;
    }

    /**
     * Sets the backpointer to the {@link ExpressionRegistry} with which this {@link JPQLQueryBNF}
     * was registered.
     *
     * @param expressionRegistry The registry for a given JPQL grammar
     */
    final void setExpressionRegistry(ExpressionRegistry expressionRegistry) {
        this.expressionRegistry = expressionRegistry;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append("(id=");
        sb.append(id);
        sb.append(", identifiers=");
        sb.append(Arrays.toString(identifiers));
        sb.append(")");
        return sb.toString();
    }
}
