/*
 * Copyright (c) 1998, 2020 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.*;

import org.eclipse.persistence.exceptions.JPQLException;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReportQuery;

/**
 * INTERNAL
 * <p><b>Purpose</b>: Represent a constructor node (NEW)
 * <p><b>Responsibilities</b>:<ul>
 * <li> Generate the correct expression for a constructor
 * </ul>
 */
public class ConstructorNode extends Node implements AliasableNode {

    /** The name of the constructor class. */
    private String className = null;

    /** The list of constructor call argument nodes */
    public List constructorItems = new ArrayList();

    /**
     * Return a new ConstructorNode
     */
    public ConstructorNode(String className) {
        this.className = className;
    }

    /**
     * INTERNAL
     * Apply this node to the passed query
     */
    @Override
    public void applyToQuery(ObjectLevelReadQuery theQuery, GenerationContext context) {
        if (theQuery instanceof ReportQuery) {
            SelectGenerationContext selectContext = (SelectGenerationContext)context;
            ReportQuery reportQuery = (ReportQuery)theQuery;
            reportQuery.beginAddingConstructorArguments(
                getConstructorClass(context.getParseTreeContext()));
            for (Iterator i = constructorItems.iterator(); i.hasNext();) {
                Node node = (Node)i.next();
                if (selectingRelationshipField(node, context)) {
                    selectContext.useOuterJoins();
                }
                node.applyToQuery(reportQuery, context);
                selectContext.dontUseOuterJoins();
            }
            reportQuery.endAddingToConstructorItem();
        }
    }

    /**
     * INTERNAL
     * Validate node and calculate its type.
     */
    @Override
    public void validate(ParseTreeContext context) {
        for (Iterator i = constructorItems.iterator(); i.hasNext();) {
            Node item = (Node)i.next();
            item.validate(context);
        }

        // Resolve constructor class
        TypeHelper typeHelper = context.getTypeHelper();
        Object type = typeHelper.resolveTypeName(className);
        if (type == null) {
            String name = className;
            // check for inner classes
            int index = name.lastIndexOf('.');
            if (index != -1) {
                name = name.substring(0, index) + '$' + name.substring(index+1);
                type = typeHelper.resolveTypeName(name);
            }
        }
        setType(type);
    }

    /**
     * INTERNAL
     * Is this node a ConstructorNode
     */
    @Override
    public boolean isConstructorNode() {
        return true;
    }

    /**
     * INTERNAL
     * Add an Order By Item to this node
     */
    public void addConstructorItem(Object theNode) {
        constructorItems.add(theNode);
    }

    /**
     * INTERNAL
     * Set the list of constructor items of this node.
     */
    public void setConstructorItems(List items) {
        this.constructorItems = items;
    }

    /**
     * INTERNAL
     * Get the list of constructor items of this node.
     */
    public List getConstructorItems() {
        return this.constructorItems;
    }

    /**
     * Check the specific constructor class and return its class instance.
     * @exception JPQLException if the specified constructor class could not
     * be found.
     */
    private Class getConstructorClass(ParseTreeContext context) {
        Object type = getType();
        if (type == null) {
            throw JPQLException.constructorClassNotFound(
                context.getQueryInfo(), getLine(), getColumn(), className);
        }
        return (Class)type;
    }

    /**
     * INTERNAL
     */
    private boolean selectingRelationshipField(Node node, GenerationContext context) {
        if ((node == null) || !node.isDotNode()) {
            return false;
        }

        TypeHelper typeHelper = context.getParseTreeContext().getTypeHelper();
        Node path = node.getLeft();
        AttributeNode attribute = (AttributeNode)node.getRight();
        return typeHelper.isRelationship(path.getType(),
                                         attribute.getAttributeName());
    }

    /**
     * INTERNAL
     * Get the string representation of this node.
     */
    @Override
    public String getAsString() {
        StringBuilder repr = new StringBuilder();
        repr.append("NEW ").append(className);
        repr.append("(");
        for (Iterator i = constructorItems.iterator(); i.hasNext();) {
            Node node = (Node)i.next();
            repr.append(node.getAsString());
            if (i.hasNext()) {
                repr.append(", ");
            }
        }
        repr.append(")");
        return repr.toString();
    }

    @Override
    public boolean isAliasableNode(){
        return true;
    }
}
