/*
 * 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.AbstractDoubleEncapsulatedExpression;
import static org.eclipse.persistence.jpa.jpql.parser.AbstractExpression.*;

/**
 * This {@link StateObject} represents a JPQL expression that has a JPQL identifier followed by
 * two an encapsulated expression with parenthesis, the two expression are separated by a comma.
 *
 * <div><p><b>BNF:</b> <code>expression ::= &lt;identifier&gt;(first_expression, second_expression)</code></p></div>
 *
 * @see ModExpressionStateObject
 * @see NullIfExpressionStateObject
 *
 * @see AbstractDoubleEncapsulatedExpression
 *
 * @version 2.4
 * @since 2.4
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public abstract class AbstractDoubleEncapsulatedExpressionStateObject extends AbstractEncapsulatedExpressionStateObject {

    /**
     * The {@link StateObject} representing the first expression.
     */
    private StateObject firstStateObject;

    /**
     * The {@link StateObject} representing the second expression.
     */
    private StateObject secondStateObject;

    /**
     * Notifies the first {@link StateObject} property has changed.
     */
    public static final String FIRST_STATE_OBJECT_PROPERTY = "firstStateObject";

    /**
     * Notifies the second {@link StateObject} property has changed.
     */
    public static final String SECOND_STATE_OBJECT_PROPERTY = "secondStateObject";

    /**
     * Creates a new <code>AbstractDoubleEncapsulatedExpressionStateObject</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 AbstractDoubleEncapsulatedExpressionStateObject(StateObject parent) {
        super(parent);
    }

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

        super(parent);
        this.firstStateObject  = parent(firstStateObject);
        this.secondStateObject = parent(secondStateObject);
    }

    /**
     * Creates a new <code>AbstractDoubleEncapsulatedExpressionStateObject</code>.
     *
     * @param parent The parent of this state object, which cannot be <code>null</code>
     * @param firstJpqlFragment The string representation of the first encapsulated expression to
     * parse and to convert into a {@link StateObject} representation
     * @param secondJpqlFragment The string representation of the second encapsulated expression to
     * parse and to convert into a {@link StateObject} representation
     * @exception NullPointerException The given parent cannot be <code>null</code>
     */
    public AbstractDoubleEncapsulatedExpressionStateObject(StateObject parent,
                                                           String firstJpqlFragment,
                                                           String secondJpqlFragment) {

        super(parent);
        parseFirst(firstJpqlFragment);
        parseSecond(secondJpqlFragment);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void addChildren(List<StateObject> children) {

        super.addChildren(children);

        if (firstStateObject != null) {
            children.add(firstStateObject);
        }

        if (secondStateObject != null) {
            children.add(secondStateObject);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public AbstractDoubleEncapsulatedExpression getExpression() {
        return (AbstractDoubleEncapsulatedExpression) super.getExpression();
    }

    /**
     * Returns the {@link StateObject} representing the first expression.
     *
     * @return The first encapsulated {@link StateObject} or <code>null</code> if none exists
     */
    public StateObject getFirst() {
        return firstStateObject;
    }

    /**
     * Returns the unique identifier of the BNF that will be used to parse a JPQL fragment as the
     * first encapsulated expression.
     *
     * @return The query BNF ID for the first encapsulated expression
     */
    protected abstract String getFirstQueryBNFId();

    /**
     * Returns the {@link StateObject} representing the second expression.
     *
     * @return The second encapsulated {@link StateObject} or <code>null</code> if none exists
     */
    public StateObject getSecond() {
        return secondStateObject;
    }

    /**
     * Returns the unique identifier of the BNF that will be used to parse a JPQL fragment as the
     * second encapsulated expression.
     *
     * @return The query BNF ID for the second encapsulated expression
     */
    protected abstract String getSecondQueryBNFId();

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

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

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isEquivalent(StateObject stateObject) {

        if (super.isEquivalent(stateObject)) {
            AbstractDoubleEncapsulatedExpressionStateObject encapsulated = (AbstractDoubleEncapsulatedExpressionStateObject) stateObject;
            return areEquivalent(firstStateObject,  encapsulated.firstStateObject) &&
                   areEquivalent(secondStateObject, encapsulated.secondStateObject);
        }

        return false;
    }

    /**
     * Parses the given JPQL fragment, which will represent the first encapsulated expression.
     *
     * @param jpqlFragment The string representation of the first encapsulated expression to parse and
     * to convert into a {@link StateObject} representation
     */
    public void parseFirst(String jpqlFragment) {
        StateObject stateObject = buildStateObject(jpqlFragment, getFirstQueryBNFId());
        setFirst(stateObject);
    }

    /**
     * Parses the given JPQL fragment, which will represent the second encapsulated expression.
     *
     * @param jpqlFragment The string representation of the second encapsulated expression to parse and
     * to convert into a {@link StateObject} representation
     */
    public void parseSecond(String jpqlFragment) {
        StateObject stateObject = buildStateObject(jpqlFragment, getSecondQueryBNFId());
        setSecond(stateObject);
    }

    /**
     * Sets the given {@link StateObject} to represent the first encapsulated expression.
     *
     * @param firstStateObject The new encapsulated {@link StateObject} representing the first
     * expression
     */
    public void setFirst(StateObject firstStateObject) {
        StateObject oldFirstStateObject = this.firstStateObject;
        this.firstStateObject = parent(firstStateObject);
        firePropertyChanged(FIRST_STATE_OBJECT_PROPERTY, oldFirstStateObject, firstStateObject);
    }

    /**
     * Sets the given {@link StateObject} to represent the second encapsulated expression.
     *
     * @param secondStateObject The new encapsulated {@link StateObject} representing the second
     * expression
     */
    public void setSecond(StateObject secondStateObject) {
        StateObject oldSecondStateObject = this.firstStateObject;
        this.secondStateObject = parent(secondStateObject);
        firePropertyChanged(SECOND_STATE_OBJECT_PROPERTY, oldSecondStateObject, secondStateObject);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void toTextEncapsulatedExpression(Appendable writer) throws IOException {

        if (firstStateObject != null) {
            firstStateObject.toString(writer);
            writer.append(SPACE);
        }

        writer.append(COMMA);

        if (secondStateObject != null) {
            writer.append(SPACE);
            secondStateObject.toString(writer);
        }
    }
}
