/*
 * 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.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.JPQLException;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.querykeys.QueryKey;

/**
 * INTERNAL
 * <p><b>Purpose</b>: Represent a attribute.
 *
 * <p><b>Responsibilities</b>:
 *
 */
public class AttributeNode extends Node {

    /** The attribute name. */
    private String name;

    /** Flag indicating outer join */
    private boolean outerJoin;

    /** */
    private boolean requiresCollectionAttribute;

    /** */
    private DatabaseMapping mapping;

    private String castClassName = null;

    private QueryKey attributeQueryKey = null;

    /**
     * Create a new AttributeNode
     */
    public AttributeNode() {
        super();
    }

    /**
     * Create a new AttributeNode with the passed name
     * @param name the attribute name
     */
    public AttributeNode(String name) {
        setAttributeName(name);
    }

    /**
     * INTERNAL
     * If called this AttributeNode represents an unqualified field access.
     * The method returns a DotNode representing a qualified field access with
     * the base variable as left child node and the attribute as right child
     * node.
     */
    @Override
    public Node qualifyAttributeAccess(ParseTreeContext context) {
        return (Node)context.getNodeFactory().newQualifiedAttribute(
            getLine(), getColumn(), context.getBaseVariable(), name);
    }

    /**
     * INTERNAL
     * Validate the current node and calculates its type.
     */
    @Override
    public void validate(ParseTreeContext context) {
        // The type is calculated in the parent DotNode.
    }

    public Expression appendCast(Expression exp, GenerationContext context){
        if (castClassName == null){
            return exp;
        }
        TypeHelper typeHelper = context.getParseTreeContext().getTypeHelper();
        Class<?> cast = (Class<?>)typeHelper.resolveSchema(castClassName);
        return exp.treat(cast);
    }

    public Object computeActualType(Object initialType, TypeHelper typeHelper){
        if (castClassName != null){
            return typeHelper.resolveSchema(castClassName);
        }
        return initialType;
    }

    public void checkForQueryKey(Object ownerType, TypeHelper typeHelper){
        attributeQueryKey = typeHelper.resolveQueryKey(ownerType, name);
    }

    /** */
    @Override
    public Expression addToExpression(Expression parentExpression, GenerationContext context) {
        if (isCollectionAttribute()) {
            //special case for NOT MEMBER OF
            if (context.hasMemberOfNode()) {
                return parentExpression.noneOf(name, new ExpressionBuilder().equal(context.getMemberOfNode().getLeftExpression()));
            }
            return outerJoin ? appendCast(parentExpression.anyOfAllowingNone(name), context) :
                appendCast(parentExpression.anyOf(name), context);
        } else {
            // check whether collection attribute is required
            if (requiresCollectionAttribute()) {
                throw JPQLException.invalidCollectionMemberDecl(
                    context.getParseTreeContext().getQueryInfo(),
                    getLine(), getColumn(), name);
            }

            if (context.shouldUseOuterJoins() || isOuterJoin()) {
                return appendCast(parentExpression.getAllowingNull(name), context);
            } else {
                return appendCast(parentExpression.get(name), context);
            }
        }
    }

    /**
     * INTERNAL
     * Is this node an AttributeNode
     */
    @Override
    public boolean isAttributeNode() {
        return true;
    }

    /** */
    public String getAttributeName() {
        return name;
    }

    /** */
    public void setAttributeName(String name) {
        this.name = name;
    }

    public String getCastClassName() {
        return castClassName;
    }

    public void setCastClassName(String castClassName) {
        this.castClassName = castClassName;
    }

    /** */
    public boolean isOuterJoin() {
        return outerJoin;
    }

    /** */
    public void setOuterJoin(boolean outerJoin) {
        this.outerJoin = outerJoin;
    }

    /** */
    public boolean requiresCollectionAttribute() {
        return requiresCollectionAttribute;
    }

    /** */
    public void setRequiresCollectionAttribute(boolean requiresCollectionAttribute) {
        this.requiresCollectionAttribute = requiresCollectionAttribute;
    }

    /** */
    public DatabaseMapping getMapping() {
        return mapping;
    }

    /** */
    public void setMapping(DatabaseMapping mapping) {
        this.mapping = mapping;
    }

    /** */
    public boolean isCollectionAttribute() {
        DatabaseMapping mapping = getMapping();
        return ((mapping != null) && mapping.isCollectionMapping()) || (attributeQueryKey != null && attributeQueryKey.isCollectionQueryKey());
    }

    /**
     * resolveMapping: Answer the mapping which corresponds to my variableName.
     */
    @Override
    public DatabaseMapping resolveMapping(GenerationContext context, Class<?> ownerClass) {
        ClassDescriptor descriptor = context.getSession().getDescriptor(ownerClass);
        return (descriptor==null) ? null : descriptor.getObjectBuilder().getMappingForAttributeName(getAttributeName());
    }

    /**
     * resolveClass: Answer the class for the mapping associated with the my variableName in the ownerClass.
     * Answer null if the node represents a mapping that doesn't exist
     */
    @Override
    public Class<?> resolveClass(GenerationContext context, Class<?> ownerClass) {
        DatabaseMapping mapping;

        mapping = resolveMapping(context, ownerClass);

        // if we are working with a direct-to-field, or the mapping's null,
        // return the owner class
        // Returning the ownerClass when the mapping is null delegates error handling
        // to the query rather than me
        if ((mapping == null) || (mapping.isDirectToFieldMapping())) {
            return ownerClass;
        }

        ClassDescriptor descriptor = mapping.getReferenceDescriptor();
        return (descriptor==null) ? null : descriptor.getJavaClass();
        //return mapping.getReferenceDescriptor().getJavaClass();
    }

    @Override
    public String toString(int indent) {
        StringBuilder buffer = new StringBuilder();
        toStringIndent(indent, buffer);
        buffer.append(toStringDisplayName()).append("[").append(getAttributeName()).append("]");
        return buffer.toString();
    }

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