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

import java.io.IOException;
import java.util.List;
import org.eclipse.persistence.jpa.jpql.parser.AbstractSingleEncapsulatedExpression;

/**
 * This {@link StateObject} represents a JPQL expression that has a JPQL identifier followed by
 * an encapsulated expression with parenthesis.
 *
 * <div><p><b>BNF:</b> <code>expression ::= &lt;identifier&gt;(expression)</code></p></div>
 *
 * @see org.eclipse.persistence.jpa.jpql.parser.AbstractSingleEncapsulatedExpression AbstractSingleEncapsulatedExpression
 *
 * @version 2.4
 * @since 2.4
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public abstract class AbstractSingleEncapsulatedExpressionStateObject extends AbstractEncapsulatedExpressionStateObject {

    /**
     * The {@link StateObject} representing the encapsulated expression.
     */
    private StateObject stateObject;

    /**
     * Notifies the encapsulated {@link StateObject} has changed.
     */
    public static final String STATE_OBJECT_PROPERTY = "stateObject";

    /**
     * Creates a new <code>AbstractSingleEncapsulatedExpressionStateObject</code>.
     *
     * @param parent The parent of this state object, which cannot be <code>null</code>
     * @exception NullPointerException The given parent cannot be <code>null</code>
     */
    protected AbstractSingleEncapsulatedExpressionStateObject(StateObject parent) {
        super(parent);
    }

    /**
     * Creates a new <code>AbstractSingleEncapsulatedExpressionStateObject</code>.
     *
     * @param parent The parent of this state object, which cannot be <code>null</code>
     * @param stateObject The {@link StateObject} representing the encapsulated expression
     * @exception NullPointerException The given parent cannot be <code>null</code>
     */
    protected AbstractSingleEncapsulatedExpressionStateObject(StateObject parent,
                                                              StateObject stateObject) {

        super(parent);
        this.stateObject = parent(stateObject);
    }

    /**
     * Creates a new <code>AbstractSingleEncapsulatedExpressionStateObject</code>.
     *
     * @param parent The parent of this state object, which cannot be <code>null</code>
     * @param jpqlFragment The portion of the query representing the encapsulated expression
     * @exception NullPointerException The given parent cannot be <code>null</code>
     */
    protected AbstractSingleEncapsulatedExpressionStateObject(StateObject parent,
                                                              String jpqlFragment) {

        super(parent);
        parse(jpqlFragment);
    }

    @Override
    protected void addChildren(List<StateObject> children) {
        super.addChildren(children);
        if (stateObject != null) {
            children.add(stateObject);
        }
    }

    @Override
    public AbstractSingleEncapsulatedExpression getExpression() {
        return (AbstractSingleEncapsulatedExpression) super.getExpression();
    }

    /**
     * Returns the unique identifier of the {@link org.eclipse.persistence.jpa.jpql.parser.JPQLQueryBNF
     * JPQLQueryBNF} that will determine how to parse the encapsulated expression.
     *
     * @return The non-<code>null</code> ID of the BNF
     */
    protected abstract String getQueryBNFId();

    /**
     * Returns the encapsulated {@link StateObject}.
     *
     * @return The encapsulated {@link StateObject}
     */
    public StateObject getStateObject() {
        return stateObject;
    }

    /**
     * Determines whether the {@link StateObject} representing the encapsulated expression is present
     * or not.
     *
     * @return <code>true</code> if the encapsulated {@link StateObject} is not <code>null</code>;
     * <code>false</code> otherwise
     */
    public boolean hasStateObject() {
        return getStateObject() != null;
    }

    @Override
    public boolean isEquivalent(StateObject stateObject) {

        if (super.isEquivalent(stateObject)) {
            AbstractSingleEncapsulatedExpressionStateObject encapsulated = (AbstractSingleEncapsulatedExpressionStateObject) stateObject;
            return areEquivalent(stateObject, encapsulated.stateObject);
        }

        return false;
    }

    /**
     * Parses the given JPQL fragment, which represents the encapsulated expression, and creates the
     * {@link StateObject}.
     *
     * @param jpqlFragment The portion of the query representing the encapsulated expression
     */
    public void parse(String jpqlFragment) {
        StateObject stateObject = buildStateObject(jpqlFragment, getQueryBNFId());
        setStateObject(stateObject);
    }

    /**
     * Sets the given {@link StateObject} to represent the new encapsulated expression.
     *
     * @param stateObject The new encapsulated {@link StateObject}
     */
    protected void setStateObject(StateObject stateObject) {
        StateObject oldStateObject = this.stateObject;
        this.stateObject = parent(stateObject);
        firePropertyChanged(STATE_OBJECT_PROPERTY, oldStateObject, stateObject);
    }

    @Override
    protected void toTextEncapsulatedExpression(Appendable writer) throws IOException {
        if (stateObject != null) {
            stateObject.toString(writer);
        }
    }
}
