/*
 * Copyright (c) 2006, 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.ArrayList;
import java.util.List;
import java.util.ListIterator;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariableDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.JoinBNF;
import org.eclipse.persistence.jpa.jpql.utility.iterable.ListIterable;
import org.eclipse.persistence.jpa.jpql.utility.iterable.SnapshotCloneListIterable;
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 AbstractIdentificationVariableDeclarationStateObject extends AbstractListHolderStateObject<JoinStateObject>
                                                                           implements VariableDeclarationStateObject {

    /**
     * The state object of the range variable declaration.
     */
    private AbstractRangeVariableDeclarationStateObject rangeVariableDeclaration;

    /**
     * Notifies the content of the list of {@link JoinStateObject} has changed.
     */
    public static final String JOINS_LIST = "joins";

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

    /**
     * Creates a new <code>AbstractIdentificationVariableDeclarationStateObject</code>.
     *
     * @param parent The parent of this state object, which cannot be <code>null</code>
     * @param root The "root" object
     * @param identificationVariable The identification variable defining the given path
     * @exception NullPointerException The given parent cannot be <code>null</code>
     */
    protected AbstractIdentificationVariableDeclarationStateObject(AbstractFromClauseStateObject parent,
                                                                   String root,
                                                                   String identificationVariable) {
        super(parent);
        setRootPath(root);
        setIdentificationVariable(identificationVariable);
    }

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

    /**
     * Adds a new <code><b>INNER JOIN</b></code> expression to this declaration.
     *
     * @param path The join association path expression
     * @param identificationVariable The new variable defining the join association path
     * @return A new {@link JoinStateObject}
     */
    public JoinStateObject addInnerJoin(String path, String identificationVariable) {
        return addJoin(INNER_JOIN, path, identificationVariable);
    }

    /**
     * Adds a new <code><b>JOIN</b></code> expression to this declaration.
     *
     * @param joinType One of the joining types: <code><b>LEFT JOIN</b></code>, <code><b>LEFT OUTER
     * JOIN</b></code>, <code><b>INNER JOIN</b></code> or <code><b>JOIN</b></code>
     * @return A new {@link JoinStateObject}
     */
    public JoinStateObject addJoin(String joinType) {
        JoinStateObject stateObject = new JoinStateObject(this, joinType, false);
        addItem(stateObject);
        return stateObject;
    }

    /**
     * Adds a new <code><b>JOIN</b></code> expression to this declaration.
     *
     * @param joinType One of the joining types: <code><b>LEFT JOIN</b></code>, <code><b>LEFT OUTER
     * JOIN</b></code>, <code><b>INNER JOIN</b></code> or <code><b>JOIN</b></code>
     * @param paths The join association path expression
     * @param identificationVariable The new variable defining the join association path
     * @return A new {@link JoinStateObject}
     */
    public JoinStateObject addJoin(String joinType, ListIterator<String> paths, String identificationVariable) {
        JoinStateObject stateObject = addJoin(joinType);
        stateObject.setJoinAssociationPaths(paths);
        stateObject.setIdentificationVariable(identificationVariable);
        return stateObject;
    }

    /**
     * Adds a new <code><b>JOIN</b></code> expression to this declaration.
     *
     * @param path The join association path expression
     * @param identificationVariable The new variable defining the join association path
     * @return A new {@link JoinStateObject}
     */
    public JoinStateObject addJoin(String path, String identificationVariable) {
        return addJoin(JOIN, path, identificationVariable);
    }

    /**
     * Adds a new <code><b>JOIN</b></code> expression to this declaration.
     *
     * @param joinType One of the joining types: <code><b>LEFT JOIN</b></code>, <code><b>LEFT OUTER
     * JOIN</b></code>, <code><b>INNER JOIN</b></code> or <code><b>JOIN</b></code>
     * @param path The join association path expression
     * @param identificationVariable The new variable defining the join association path
     * @return A new {@link JoinStateObject}
     */
    public JoinStateObject addJoin(String joinType, String path, String identificationVariable) {
        JoinStateObject stateObject = addJoin(joinType);
        stateObject.setJoinAssociationPath(path);
        stateObject.setIdentificationVariable(identificationVariable);
        return stateObject;
    }

    /**
     * Adds a new <code><b>LEFT JOIN</b></code> expression to this declaration.
     *
     * @param path The join association path expression
     * @param identificationVariable The new variable defining the join association path
     * @return A new {@link JoinStateObject}
     */
    public JoinStateObject addLeftJoin(String path, String identificationVariable) {
        return addJoin(LEFT_JOIN, path, identificationVariable);
    }

    /**
     * Adds a new <code><b>LEFT OUTER JOIN</b></code> expression to this declaration.
     *
     * @param path The join association path expression
     * @param identificationVariable The new variable defining the join association path
     * @return A new {@link JoinStateObject}
     */
    public JoinStateObject addLeftOuterJoin(String path, String identificationVariable) {
        return addJoin(LEFT_OUTER_JOIN, path, identificationVariable);
    }

    /**
     * Creates
     *
     * @return
     */
    protected abstract AbstractRangeVariableDeclarationStateObject buildRangeVariableDeclarationStateObject();

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

    /**
     * Returns the identification variable identifying the "root".
     *
     * @return A case insensitive unique identifier declaring the "root" of the declaration
     */
    public String getIdentificationVariable() {
        return getRangeVariableDeclaration().getIdentificationVariable();
    }

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

    @Override
    public AbstractFromClauseStateObject getParent() {
        return (AbstractFromClauseStateObject) super.getParent();
    }

    /**
     * Returns the {@link StateObject} representing the range variable declaration portion.
     *
     * @return The concrete instance
     */
    public AbstractRangeVariableDeclarationStateObject getRangeVariableDeclaration() {
        return rangeVariableDeclaration;
    }

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

    /**
     * Returns the {@link StateObject} representing the "root" for objects which may not be
     * reachable by navigation.
     *
     * @return The {@link StateObject} representing one of the possible valid "root"
     */
    public StateObject getRootStateObject() {
        return getRangeVariableDeclaration().getRootStateObject();
    }

    @Override
    public ListIterable<IdentificationVariableStateObject> identificationVariables() {
        List<IdentificationVariableStateObject> stateObjects = new ArrayList<IdentificationVariableStateObject>();
        stateObjects.add(rangeVariableDeclaration.getIdentificationVariableStateObject());
        for (JoinStateObject join : items()) {
            stateObjects.add(join.getIdentificationVariableStateObject());
        }
        return new SnapshotCloneListIterable<IdentificationVariableStateObject>(stateObjects);
    }

    @Override
    protected void initialize() {
        super.initialize();
        rangeVariableDeclaration = buildRangeVariableDeclarationStateObject();
    }

    @Override
    public boolean isEquivalent(StateObject stateObject) {

        if (super.isEquivalent(stateObject)) {
            AbstractIdentificationVariableDeclarationStateObject declaration = (AbstractIdentificationVariableDeclarationStateObject) stateObject;
            return rangeVariableDeclaration.isEquivalent(declaration.rangeVariableDeclaration) &&
                   areChildrenEquivalent(declaration);
        }

        return false;
    }

    @Override
    protected String listName() {
        return JOINS_LIST;
    }

    /**
     * Parses the given JPQL fragment that should contain a single <code><b>JOIN</b></code>
     * expression.
     *
     * @param jpqlFragment The portion representing a <code><b>JOIN</b></code> expression
     */
    public void parseJoin(String jpqlFragment) {
        // The JoinStateObject is automatically added to this state object
        buildStateObject(jpqlFragment, JoinBNF.ID);
    }

    /**
     * Keeps a reference of the {@link IdentificationVariableDeclaration 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 IdentificationVariableDeclaration parsed object} representing an
     * identification variable declaration
     */
    public void setExpression(IdentificationVariableDeclaration expression) {
        super.setExpression(expression);
    }

    /**
     * Sets the new identification variable that will range over the "root".
     *
     * @param identificationVariable The new identification variable
     */
    public void setIdentificationVariable(String identificationVariable) {
        rangeVariableDeclaration.setIdentificationVariable(identificationVariable);
    }

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

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

        rangeVariableDeclaration.toString(writer);

        if (itemsSize() > 0) {
            writer.append(SPACE);
            toStringItems(writer, false);
        }
    }
}
