/*
 * 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;


// Java imports
import java.util.*;

// TopLink imports
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.queries.ReportQuery;
import org.eclipse.persistence.exceptions.JPQLException;

/**
 * INTERNAL
 * <p><b>Purpose</b>: Represent an IN in EJBQL
 * <p><b>Responsibilities</b>:<ul>
 * <li> Generate the correct expression for an IN
 * </ul>
 *    @author Jon Driscoll and Joel Lucuik
 *    @since TopLink 4.0
 */
public class InNode extends SimpleConditionalExpressionNode {

    private List<Node> theObjects = null;

    //Was NOT indicated? "WHERE emp.lastName NOT IN (...)
    private boolean notIndicated = false;

    private boolean isListParameterOrSubquery = false;

    /**
     * InNode constructor comment.
     */
    public InNode() {
        super();
    }

    /**
     * INTERNAL
     * Add the passed node value to the collection of object for this node
     */
    public void addNodeToTheObjects(Node theNode) {
        getTheObjects().add(theNode);
    }

    /**
     * INTERNAL
     * Validate the current node and calculates its type.
     */
    @Override
    public void validate(ParseTreeContext context) {
        Object leftType = null;
        TypeHelper typeHelper = context.getTypeHelper();

        if (left != null) {
            left.validate(context);
            // check to see if the argument is a parameter
            if (isListParameterOrSubquery && !getTheObjects().isEmpty() && getTheObjects().get(0).isParameterNode()){
                leftType = Collection.class;
            } else {
                leftType = left.getType();
            }
        }
        for (Iterator<Node> i = getTheObjects().iterator(); i.hasNext();) {
            Node node = i.next();
            node.validate(context);
            node.validateParameter(context, leftType);
            Object nodeType = node.getType();
            if ((leftType != null) && !typeHelper.isAssignableFrom(leftType, nodeType))
                throw JPQLException.invalidExpressionArgument(
                    context.getQueryInfo(), node.getLine(), node.getColumn(),
                    "IN", node.getAsString(), typeHelper.getTypeName(leftType));
        }

        setType(typeHelper.getBooleanType());
    }

    /**
     * INTERNAL
     * Return the EclipseLink expression for this node
     */
    @Override
    public Expression generateExpression(GenerationContext context) {
        Expression whereClause = getLeft().generateExpression(context);
        List<Node> arguments = getTheObjects();
        Node firstArg = arguments.get(0);
        if (firstArg.isSubqueryNode()) {
            SubqueryNode subqueryNode = (SubqueryNode)firstArg;
            ReportQuery reportQuery = subqueryNode.getReportQuery(context);
            if (notIndicated()) {
                whereClause = whereClause.notIn(reportQuery);
            }
            else {
                whereClause = whereClause.in(reportQuery);
            }
        } else if (isListParameterOrSubquery && firstArg.isParameterNode()) {
            if (notIndicated()) {
                whereClause = whereClause.notIn(firstArg.generateExpression(context));
            } else {
                whereClause = whereClause.in(firstArg.generateExpression(context));
            }
        } else {
            Vector<Expression> inArguments = new Vector<>(arguments.size());
            for (Iterator<Node> iter = arguments.iterator(); iter.hasNext();) {
                Node nextNode = iter.next();
                inArguments.add(nextNode.generateExpression(context));
            }
            if (inArguments.size() > 0) {
                if (notIndicated()) {
                    whereClause = whereClause.notIn(inArguments);
                } else {
                    whereClause = whereClause.in(inArguments);
                }
            }
        }
        return whereClause;
    }

    /**
     * INTERNAL
     * Return the collection of the objects used as parameters for this node
     */
    public List<Node> getTheObjects() {
        if (theObjects == null) {
            setTheObjects(new Vector<>());
        }
        return theObjects;
    }

    /**
     * INTERNAL:
     * This method is called to indicate that the inNode has a single argument.  This will be either a
     * subquery or a single parameter that contains the list of items to test
     */
    public void setIsListParameterOrSubquery(boolean isListParameterOrSubquery){
        this.isListParameterOrSubquery = isListParameterOrSubquery;
    }

    /**
     * INTERNAL
     * Set this node's object collection to the passed value
     */
    public void setTheObjects(List<Node> newTheObjects) {
        theObjects = newTheObjects;
    }

    /**
     * INTERNAL
     * Indicate if a NOT was found in the WHERE clause.
     * Examples:
     *        ...WHERE ... NOT IN(...)
     */
    public void indicateNot() {
        notIndicated = true;
    }

    public boolean notIndicated() {
        return notIndicated;
    }
}
