/*
 * 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.exceptions.JPQLException;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.internal.expressions.*;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.foundation.AbstractDirectMapping;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReportQuery;

/**
 * INTERNAL
 * <p><b>Purpose</b>: This node represents an 'DOT' (i.e. '.') on the input
 * stream. The left and right will depend on the input stream.
 * <p><b>Responsibilities</b>:
 *
 *    @author Jon Driscoll and Joel Lucuik
 *    @since TopLink 4.0
 */
public class DotNode extends LogicalOperatorNode implements AliasableNode {

    private Object enumConstant;

    /**
     * INTERNAL
     * Apply this node to the passed query
     */
    @Override
    public void applyToQuery(ObjectLevelReadQuery theQuery, GenerationContext context) {
        if (theQuery.isReportQuery()){
            ReportQuery reportQuery = (ReportQuery)theQuery;
            reportQuery.addAttribute(resolveAttribute(), generateExpression(context));
            reportQuery.dontRetrievePrimaryKeys();
        }
    }

    /**
     * INTERNAL
     * Check the left child node for an unqualified field access. The method
     * delegates to the left most expression of multi-navigation path
     * expression.
     */
    @Override
    public Node qualifyAttributeAccess(ParseTreeContext context) {
        if (getLeft() != null) {
            setLeft(getLeft().qualifyAttributeAccess(context));
        }
        return this;
    }

    /**
     * INTERNAL
     * Validate node and calculate its type.
     * Check for enum literals.
     */
    @Override
    public void validate(ParseTreeContext context) {
        TypeHelper typeHelper = context.getTypeHelper();
        String name = ((AttributeNode)right).getAttributeName();
        // check for fully qualified type names
        Node leftMost = getLeftMostNode();
        if (isDeclaredVariable(leftMost, context)) {
            left.validate(context);
            checkNavigation(left, context);
            Object type = null;
            if (left.isVariableNode()){
                Node path = context.pathForVariable(((VariableNode)left).getVariableName());
                if (path != null){
                    type = path.getType();
                    type = typeHelper.resolveAttribute(type, name);
                }
            }
            if (type == null){
                type = typeHelper.resolveAttribute(left.getType(), name);
            }
            if (type == null) {
                // could not resolve attribute
                throw JPQLException.unknownAttribute(
                    context.getQueryInfo(), right.getLine(), right.getColumn(),
                    name, typeHelper.getTypeName(left.getType()));
            }
            if (right.isAttributeNode()){
                type = ((AttributeNode)right).computeActualType(type, typeHelper);
                ((AttributeNode)right).checkForQueryKey(left.getType(), typeHelper);
            }
            setType(type);
            right.setType(type);
        } else {
            // Check for enum literal access
            String typeName = left.getAsString();
            Object type = resolveEnumTypeName(typeName, typeHelper);
            if ((type != null) && typeHelper.isEnumType(type)) {
                enumConstant = typeHelper.resolveEnumConstant(type, name);
                if (enumConstant == null) {
                    throw JPQLException.invalidEnumLiteral(context.getQueryInfo(),
                        right.getLine(), right.getColumn(), typeName, name);
                }
            } else {
                // left most node is not an identification variable and
                // dot expression does not denote an enum literal access =>
                // unknown identification variable
                throw JPQLException.aliasResolutionException(
                    context.getQueryInfo(), leftMost.getLine(),
                    leftMost.getColumn(), leftMost.getAsString());
            }
            setType(type);
            right.setType(type);
        }
    }

    /**
     * INTERNAL
     * Checks whether the left hand side of this dot node is navigable.
     */
    private void checkNavigation(Node node, ParseTreeContext context) {
        TypeHelper typeHelper = context.getTypeHelper();
        // Checks whether the type of the dot node allows a navigation.
        Object type = node.getType();
        if (!typeHelper.isEntityClass(type) &&
            !typeHelper.isEmbeddable(type) &&
            !typeHelper.isEnumType(type)) {
            throw JPQLException.invalidNavigation(
                context.getQueryInfo(), node.getLine(), node.getColumn(),
                this.getAsString(), node.getAsString(),
                typeHelper.getTypeName(type));
        }
        // Special check to disallow collection valued relationships
        if (node.isDotNode()) {
            Node left = node.getLeft();
            AttributeNode right = (AttributeNode)node.getRight();
            if (typeHelper.isCollectionValuedRelationship(
                    left.getType(), right.getAttributeName())) {
                throw JPQLException.invalidCollectionNavigation(
                    context.getQueryInfo(), right.getLine(), right.getColumn(),
                    this.getAsString(), right.getAttributeName());
            }
        }
    }

    /** */
    private boolean isDeclaredVariable(Node node, ParseTreeContext context) {
        if (node.isVariableNode()) {
            String name = ((VariableNode)node).getCanonicalVariableName();
            return context.isVariable(name);
        }
        return false;
    }

    /**
     * INTERNAL
     * Return a TopLink expression by getting the required variables using the
     * left and right nodes
     * "emp.address.city" = builder.get("address").get("city")
     */
    @Override
    public Expression generateExpression(GenerationContext context) {
        Node right = getRight();

        if (enumConstant != null) {
            // enum literal access
            return new ConstantExpression(enumConstant, new ExpressionBuilder());
        } else {
            // Get the left expression
            Expression whereClause = getLeft().generateExpression(context);

            // Calculate the mapping and pass it to the right expression
            if (right.isAttributeNode()) {
                ((AttributeNode)right).setMapping(resolveMapping(context));
            }

            // Or it with whatever the right expression is
            whereClause = right.addToExpression(whereClause, context);

            if (alias != null){
                context.addExpression(whereClause, alias);
            }
            // and return the expression...
            return whereClause;
        }
    }

    /**
     * INTERNAL
     * Yes, this is a dot node
     */
    @Override
    public boolean isDotNode() {
        return true;
    }

    /**
     * INTERNAL
     * ():
     * Answer true if the SELECTed node has a left and right, and the right represents
     * a direct-to-field mapping.
     */
    public boolean endsWithDirectToField(GenerationContext context) {
        DatabaseMapping mapping = resolveMapping(context);
        return (mapping != null) && mapping.isDirectToFieldMapping();
    }

    /**
     * INTERNAL
     * Returns the attribute type if the right represents a direct-to-field mapping.
     */
    public Class getTypeOfDirectToField(GenerationContext context) {
        DatabaseMapping mapping = resolveMapping(context);
        if ((mapping != null) && mapping.isDirectToFieldMapping()) {
            return mapping.getAttributeClassification();
        }
        return null;
    }

    public Object getTypeForMapKey(ParseTreeContext context){
        Object type = null;
        String name = ((AttributeNode)right).getAttributeName();
        Node leftMost = getLeftMostNode();
        if (isDeclaredVariable(leftMost, context)) {
            type = context.getTypeHelper().resolveMapKey(left.getType(), name);
        }
        return type;
    }
    /**
     * INTERNAL
     * ():
     * Answer true if the node has a left and right, and the right represents
     * a collection mapping.
     */
    public boolean endsWithCollectionField(GenerationContext context) {
        DatabaseMapping mapping = resolveMapping(context);
        return (mapping != null) && mapping.isCollectionMapping();
    }

    /**
     * INTERNAL
     * Answer the name of the attribute which is represented by the receiver's
     * right node.
     */
    @Override
    public String resolveAttribute() {
        return ((AttributeNode)getRight()).getAttributeName();
    }

    /**
     * INTERNAL
     * Answer the mapping resulting from traversing the receiver's nodes
     */
    @Override
    public DatabaseMapping resolveMapping(GenerationContext context) {
        Class leftClass = getLeft().resolveClass(context);
        return getRight().resolveMapping(context, leftClass);
    }

    /**
    * resolveClass: Answer the class which results from traversing the mappings for the receiver's nodes
    */
    @Override
    public Class resolveClass(GenerationContext context) {
        Class leftClass = getLeft().resolveClass(context);
        return getRight().resolveClass(context, leftClass);
    }

    /**
     * INTERNAL
     * Get the string representation of this node.
     */
    @Override
    public String getAsString() {
        return left.getAsString() + "." + right.getAsString();
    }

    /**
     * INTERNAL
     * Return the left most node of a dot expr, so return 'a' for 'a.b.c'.
     */
    public Node getLeftMostNode() {
        if (left.isDotNode()){
            return ((DotNode)left).getLeftMostNode();
        } else if (left.isMapKeyNode()){
            return ((MapKeyNode)left).getLeftMostNode();
        }
        return left;
    }

    /**
     * INTERNAL
     * Return the right most node of a dot expr, so return 'c' for 'a.b.c'.
     */
    public Node getRightMostNode() {
        if (right.isDotNode()){
            return ((DotNode)right).getRightMostNode();
        }
        return right;
    }

    /**
     * INTERNAL
     * Returns the type representation for the specified type name. The method
     * looks for inner classes if it cannot resolve the type name.
     */
    private Object resolveEnumTypeName(String name, TypeHelper helper) {
        Object type = helper.resolveTypeName(name);
        if (type == null) {
            // check for inner enum type
            int index = name.lastIndexOf('.');
            if (index != -1) {
                name = name.substring(0, index) + '$' + name.substring(index+1);
                type = helper.resolveTypeName(name);
            }
        }
        return type;
    }

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