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