/*
 * 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.RangeVariableDeclaration;
import org.eclipse.persistence.jpa.jpql.tools.model.Problem;
import org.eclipse.persistence.jpa.jpql.tools.utility.iterable.SingleElementListIterable;
import org.eclipse.persistence.jpa.jpql.utility.iterable.ListIterable;
import static org.eclipse.persistence.jpa.jpql.parser.AbstractExpression.*;

/**
 * @version 2.5
 * @since 2.4
 * @author Pascal Filion
 */
@SuppressWarnings({"nls", "unused"}) // unused used for the import statement: see bug 330740
public abstract class AbstractRangeVariableDeclarationStateObject extends AbstractStateObject
                                                                  implements VariableDeclarationStateObject {

    /**
     * Flag used to determine if the <code><b>AS</b></code> identifier is used or not.
     */
    private boolean as;

    /**
     * The state object representing the identification variable used to reach the "root" object.
     */
    private IdentificationVariableStateObject identificationVariable;

    /**
     * Flag used to determine if the identification variable is optional or not, which is <code>true</code>
     * only when this is used by {@link UpdateClauseStateObject} or by {@link DeleteClauseStateObject}.
     */
    private boolean identificationVariableOptional;

    /**
     * The state object holding the "root" for objects which may not be reachable by navigation.
     */
    private StateObject rootStateObject;

    /**
     * Notifies the visibility of the <code><b>AS</b></code> identifier has changed.
     */
    public static final String AS_PROPERTY = "as";

    /**
     * Notifies the identification variable property has changed.
     */
    public static final String IDENTIFICATION_VARIABLE_PROPERTY = "identificationVariable";

    /**
     * Creates a new <code>RangeVariableDeclarationStateObject</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>
     */
    public AbstractRangeVariableDeclarationStateObject(AbstractIdentificationVariableDeclarationStateObject parent) {
        super(parent);
    }

    /**
     * Creates a new <code>RangeVariableDeclarationStateObject</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>
     */
    public AbstractRangeVariableDeclarationStateObject(AbstractIdentificationVariableDeclarationStateObject parent,
                                                       String root) {
        super(parent);
        setRootPath(root);
    }

    /**
     * Creates a new <code>AbstractRangeVariableDeclarationStateObject</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>
     */
    public AbstractRangeVariableDeclarationStateObject(AbstractModifyClauseStateObject parent) {
        super(parent);
        setIdentificationVariableOptional(true);
    }

    /**
     * Makes sure the <code><b>AS</b></code> identifier is specified.
     *
     * @return This object
     */
    public AbstractRangeVariableDeclarationStateObject addAs() {
        if (!as) {
            setAs(true);
        }
        return this;
    }

    @Override
    protected void addChildren(List<StateObject> children) {
        super.addChildren(children);
        children.add(rootStateObject);
        children.add(identificationVariable);
    }

    @Override
    protected void addProblems(List<Problem> problems) {
        super.addProblems(problems);
        // TODO

        if (!identificationVariableOptional) {
            // validate
        }
    }

    protected abstract StateObject buildRootStateObject();

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

    /**
     * Returns the identification variable name that is ranging over the abstract schema type.
     *
     * @return The identification variable name
     */
    public String getIdentificationVariable() {
        return identificationVariable.getText();
    }

    /**
     * Returns the {@link IdentificationVariableStateObject} holding onto the identification variable.
     *
     * @return The {@link IdentificationVariableStateObject}, which is never <code>null</code>
     */
    public IdentificationVariableStateObject getIdentificationVariableStateObject() {
        return identificationVariable;
    }

    /**
     * Returns the "root" object for objects which may not be reachable by navigation.
     *
     * @return The "root" object
     */
    public abstract String getRootPath();

    /**
     * Returns the {@link StateObject} holding onto the abstract schema name.
     *
     * @return The {@link StateObject}, which is never <code>null</code>
     */
    public StateObject getRootStateObject() {
        return rootStateObject;
    }

    /**
     * Determines whether the <code><b>AS</b></code> identifier is used or not.
     *
     * @return <code>true</code> if the <code><b>AS</b></code> identifier is part of the expression;
     * <code>false</code> otherwise
     */
    public boolean hasAs() {
        return as;
    }

    /**
     * Determines whether an identification variable was defined.
     *
     * @return <code>true</code> if an identification variable is defined; <code>false</code> otherwise
     */
    public boolean hasIdentificationVariable() {
        return identificationVariable.hasText();
    }

    @Override
    public ListIterable<IdentificationVariableStateObject> identificationVariables() {
        return new SingleElementListIterable<IdentificationVariableStateObject>(identificationVariable);
    }

    @Override
    protected void initialize() {
        super.initialize();
        rootStateObject        = buildRootStateObject();
        identificationVariable = new IdentificationVariableStateObject(this);
    }

    @Override
    public boolean isEquivalent(StateObject stateObject) {

        if (super.isEquivalent(stateObject)) {
            AbstractRangeVariableDeclarationStateObject declaration = (AbstractRangeVariableDeclarationStateObject) stateObject;

            return as == declaration.as &&
                   identificationVariableOptional == declaration.identificationVariableOptional &&
                   identificationVariable.isEquivalent(declaration.identificationVariable)      &&
                   areEquivalent(rootStateObject, declaration.rootStateObject);
        }

        return false;
    }

    /**
     * Determines whether the identification variable is optional or not. The only time it is
     * optional is when this model is used in a modify clause (<code><b>DELETE</b></code> or
     * <code><b>UPDATE</b></code>).
     *
     * @return <code>true</code> if an identification variable is not required; <code>false</code> if
     * it is required
     */
    public boolean isIdentificationVariableOptional() {
        return identificationVariableOptional;
    }

    /**
     * Determines whether this identification variable is virtual, meaning it's not part of the query
     * but is required for proper navigability.
     *
     * @return <code>true</code> if this identification variable was virtually created to fully
     * qualify path expression; <code>false</code> if it was parsed
     */
    public boolean isIdentificationVariableVirtual() {
        return identificationVariable.isVirtual();
    }

    /**
     * Sets whether the <code><b>AS</b></code> identifier is used or not.
     *
     * @param as <code>true</code> if the <code><b>AS</b></code> identifier is part of the
     * expression; <code>false</code> otherwise
     */
    public void setAs(boolean as) {
        boolean oldAs = this.as;
        this.as = as;
        firePropertyChanged(AS_PROPERTY, oldAs, as);
    }

    /**
     * Keeps a reference of the {@link RangeVariableDeclaration parsed object} object, which should
     * only be* done when this object is instantiated during the conversion of a parsed JPQL query
     * into {@link StateObject StateObjects}.
     *
     * @param expression The {@link RangeVariableDeclaration parsed object} representing a range
     * variable declaration
     */
    public void setExpression(RangeVariableDeclaration expression) {
        super.setExpression(expression);
    }

    /**
     * Sets the new identification variable that will range over the "root" object.
     *
     * @param identificationVariable The new identification variable
     */
    public void setIdentificationVariable(String identificationVariable) {
        String oldIdentificationVariable = getIdentificationVariable();
        this.identificationVariable.setText(identificationVariable);
        firePropertyChanged(IDENTIFICATION_VARIABLE_PROPERTY, oldIdentificationVariable, identificationVariable);
    }

    /**
     * Sets whether the identification variable is optional or not. The only time it is optional is
     * when this model is used in a modify clause (<code><b>DELETE</b></code> or
     * <code><b>UPDATE</b></code>).
     *
     * @param identificationVariableOptional <code>true</code> if an identification variable is not
     * required; <code>false</code> if it is required
     */
    protected void setIdentificationVariableOptional(boolean identificationVariableOptional) {
        this.identificationVariableOptional = identificationVariableOptional;
    }

    /**
     * Sets the "root" object for objects which may not be reachable by navigation.
     *
     * @param root The "root" object
     */
    public abstract void setRootPath(String root);

    /**
     * Toggles the usage of the <code><b>AS</b></code> identifier.
     */
    public void toggleAs() {
        setAs(!hasAs());
    }

    @Override
    protected void toTextInternal(Appendable writer) throws IOException {

        rootStateObject.toString(writer);

        if (as) {
            writer.append(SPACE);
            writer.append(AS);

            if (!identificationVariable.isVirtual()) {
                writer.append(SPACE);
            }
        }

        if (!identificationVariable.isVirtual()) {

            if (rootStateObject != null && !as) {
                writer.append(SPACE);
            }

            identificationVariable.toString(writer);
        }
    }
}
