/*
 * Copyright (c) 1998, 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 from Oracle TopLink
package org.eclipse.persistence.internal.jpa.parsing;

import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.queries.*;
import java.util.*;

/**
 * INTERNAL:
 * This node holds a list of all the updates that will occur in an Update Query.
 * Slightly different from other nodes since holds more than two children in a list.
 */
public class SetNode extends MajorNode {
    private List <Node>assignmentNodes = null;

    public SetNode() {
        super();
        assignmentNodes = new Vector<>();
    }

    /**
     * Iterate through the updates in this query and build expressions for them.  Set the
     * built expressions on the query.
     */
    public void addUpdatesToQuery(UpdateAllQuery theQuery, GenerationContext context) {
        Iterator<Node> iterator = assignmentNodes.iterator();
        while (iterator.hasNext()) {
            EqualsAssignmentNode node = (EqualsAssignmentNode)iterator.next();
            Expression leftExpression = getExpressionForNode(node.getLeft(), theQuery.getReferenceClass(), context);
            Expression rightExpression = getExpressionForNode(node.getRight(), theQuery.getReferenceClass(), context);
            theQuery.addUpdate(leftExpression, rightExpression);
        }
    }

    /**
     * INTERNAL
     * Check the update item node for a path expression starting with a
     * unqualified field access and if so, replace it by a qualified field
     * access.
     */
    @Override
    public Node qualifyAttributeAccess(ParseTreeContext context) {
        for (Iterator<Node> i = assignmentNodes.iterator(); i.hasNext(); ) {
            Node item = i.next();
            item.qualifyAttributeAccess(context);
        }
        return this;
    }

    /**
     * INTERNAL
     * Validate node.
     */
    @Override
    public void validate(ParseTreeContext context) {
        for (Iterator<Node> i = assignmentNodes.iterator(); i.hasNext(); ) {
            Node item = i.next();
            item.validate(context);
        }
    }

    /**
     * Create an expression to represent one of the nodes on a SetToNode.
     * We will assume that set_to nodes change elements that are direct mappings on the reference
     * class of the query.
     */
    protected Expression getExpressionForNode(Node node, Class<?> referenceClass, GenerationContext context) {
        Expression expression = null;
        if (node.isAttributeNode()) {
            // look up a preexisting expression based on the reference class of the query.
            String classVariable = context.getParseTreeContext().getVariableNameForClass(referenceClass, context);
            expression = context.expressionFor(classVariable);
            if (expression == null) {
                expression = new ExpressionBuilder();
                context.addExpression(expression, classVariable);
            }
            expression = node.addToExpression(expression, context);
        } else {
            expression = node.generateExpression(context);
        }
        return expression;
    }

    /**
     * INTERNAL
     */
    public void setAssignmentNodes(List<Node> nodes) {
        assignmentNodes = nodes;
    }

}
