/*
 * 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);
    }

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

    /**
     * {@inheritDoc}
     */
    @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;
    }

    /**
     * {@inheritDoc}
     */
    @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);
    }

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