/*
 * Copyright (c) 2012, 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.Collection;
import java.util.List;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.parser.FunctionExpression;
import org.eclipse.persistence.jpa.jpql.tools.model.IListChangeListener;
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.4
 * @since 2.4
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public class FunctionExpressionStateObject extends AbstractStateObject
                                           implements ListHolderStateObject<StateObject> {

    /**
     * The name of the native database function.
     */
    private String functionName;

    /**
     * The JPQL identifier of the SQL expression.
     */
    private String identifier;

    /**
     * The list of {@link StateObject} representing the arguments to pass to the native database function.
     */
    private List<StateObject> items;

    /**
     * Notifies the list of arguments has changed.
     */
    public static final String ARGUMENTS_LIST = "arguments";

    /**
     * Notifies the function name property has changed.
     */
    public static final String FUNCTION_NAME_PROPERTY = "functionName";

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

    /**
     * Creates a new <code>AbstractFunctionExpressionStateObject</code>.
     *
     * @param parent The parent of this state object, which cannot be <code>null</code>
     * @param identifier The JPQL identifier of the SQL expression
     * @param functionName The name of the native database function
     * @param arguments The list of {@link StateObject} representing the arguments to pass to the
     * native database function
     * @exception NullPointerException The given parent cannot be <code>null</code>
     */
    public FunctionExpressionStateObject(StateObject parent,
                                         String identifier,
                                         String functionName,
                                         List<? extends StateObject> arguments) {

        super(parent);
        this.identifier = identifier;
        this.functionName = ExpressionTools.unquote(functionName);
        this.items.addAll(parent(arguments));
    }

    @Override
    public void accept(StateObjectVisitor visitor) {
        acceptUnknownVisitor(visitor);
    }

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

    @Override
    public <S extends StateObject> S addItem(S item) {
        getChangeSupport().addItem(this, items, ARGUMENTS_LIST, parent(item));
        return item;
    }

    @Override
    public void addItems(List<? extends StateObject> items) {
        getChangeSupport().addItems(this, this.items, ARGUMENTS_LIST, parent(items));
    }

    @Override
    public void addListChangeListener(String listName, IListChangeListener<StateObject> listener) {
        getChangeSupport().addListChangeListener(listName, listener);
    }

    /**
     * Determines whether the children of this {@link StateObject} are equivalent to the children
     * of the given one, i.e. the information of the {@link StateObject StateObjects} is the same.
     *
     * @param stateObject The {@link StateObject} to compare its children to this one's children
     * @return <code>true</code> if both have equivalent children; <code>false</code> otherwise
     */
    protected boolean areChildrenEquivalent(FunctionExpressionStateObject stateObject) {

        int size = itemsSize();

        if (size != stateObject.itemsSize()) {
            return false;
        }

        for (int index = size; --index >= 0; ) {

            StateObject child1 = getItem(index);
            StateObject child2 = stateObject.getItem(index);

            if (!child1.isEquivalent(child2)) {
                return false;
            }
        }

        return true;
    }

    @Override
    public boolean canMoveDown(StateObject item) {
        return getChangeSupport().canMoveDown(items, item);
    }

    @Override
    public boolean canMoveUp(StateObject item) {
        return getChangeSupport().canMoveUp(items, item);
    }

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

    /**
     * Returns the name of the native database function.
     *
     * @return The new name of the native database function
     */
    public String getFunctionName() {
        return functionName;
    }

    /**
     * Returns the JPQL identifier of this expression.
     *
     * @return The JPQL identifier
     */
    public String getIdentifier() {
        return identifier;
    }

    @Override
    public StateObject getItem(int index) {
        return items.get(index);
    }

    /**
     * Returns the quoted name of the native database function.
     *
     * @return The new name of the native database function, which is quoted
     */
    public String getQuotedFunctionName() {
        return ExpressionTools.quote(functionName);
    }

    /**
     * Determines whether the name of the native SQL function has been specified.
     *
     * @return <code>true</code> if the function name has been specified; <code>false</code>
     * otherwise
     */
    public boolean hasFunctionName() {
        return functionName != null;
    }

    @Override
    public boolean hasItems() {
        return !items.isEmpty();
    }

    @Override
    protected void initialize() {
        super.initialize();
        items = new ArrayList<StateObject>();
    }

    @Override
    public boolean isEquivalent(StateObject stateObject) {

        if (super.isEquivalent(stateObject)) {
            FunctionExpressionStateObject function = (FunctionExpressionStateObject) stateObject;
            return ExpressionTools.valuesAreEqual(functionName, function.functionName) &&
                   areChildrenEquivalent(function);
        }

        return false;
    }

    @Override
    public ListIterable<StateObject> items() {
        return new SnapshotCloneListIterable<StateObject>(items);
    }

    @Override
    public int itemsSize() {
        return items.size();
    }

    @Override
    public StateObject moveDown(StateObject item) {
        getChangeSupport().moveDown(this, items, ARGUMENTS_LIST, item);
        return item;
    }

    @Override
    public StateObject moveUp(StateObject item) {
        getChangeSupport().moveUp(this, items, ARGUMENTS_LIST, item);
        return item;
    }

    @Override
    public void removeItem(StateObject item) {
        getChangeSupport().removeItem(this, items, ARGUMENTS_LIST, item);
    }

    @Override
    public void removeItems(Collection<StateObject> items) {
        getChangeSupport().removeItems(this, this.items, ARGUMENTS_LIST, items);
    }

    @Override
    public void removeListChangeListener(String listName, IListChangeListener<StateObject> listener) {
        getChangeSupport().removeListChangeListener(listName, listener);
    }

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

    /**
     * Sets the unquoted name of the native database function.
     *
     * @param functionName The new name of the native database function, which should be unquoted
     */
    public void setFunctionName(String functionName) {
        String oldFunctionName = this.functionName;
        this.functionName = functionName;
        firePropertyChanged(FUNCTION_NAME_PROPERTY, oldFunctionName, functionName);
    }

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

        // Function name
        if (functionName != null) {
            writer.append(SINGLE_QUOTE);
            writer.append(functionName);
            writer.append(SINGLE_QUOTE);
        }

        if (hasItems()) {
            writer.append(COMMA);
            writer.append(SPACE);
            toStringItems(writer, items, true);
        }
    }
}
