/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2019 IBM Corporation. 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.queries;

import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.internal.expressions.FunctionExpression;
import org.eclipse.persistence.internal.expressions.QueryKeyExpression;

/**
 * <b>Purpose</b>: represents an item requested (i.e. field for SELECT)
 *
 * @author Doug Clarke
 * @since 2.0
 */
public class ReportItem implements Cloneable, java.io.Serializable {

    /** Expression (partial) describing the attribute wanted */
    protected Expression attributeExpression;

    /** Name given for item, can be used to retrieve value from result. Useful if same field retrieved multiple times */
    protected String name;

    /** Mapping which relates field to attribute, used to convert value and determine reference descriptor */
    protected DatabaseMapping mapping;

    /** Descriptor for object result that is not based on an expression */
    protected ClassDescriptor descriptor;

    /** Result type for this report item. */
    protected Class<?> resultType;
    /** Stores the Join information for this item */
    protected JoinedAttributeManager joinedAttributeManager;

    /** Stores the row index for this item, given multiple results and joins */
    protected int resultIndex;

    public ReportItem() {
        super();
    }

    public ReportItem(String name, Expression attributeExpression) {
        this();
        this.name = name;
        this.attributeExpression = attributeExpression;
    }

    @Override
    public Object clone(){
        try{
            return super.clone();
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }

    public Expression getAttributeExpression() {
        return attributeExpression;
    }

    public void setAttributeExpression(Expression attributeExpression) {
        this.attributeExpression = attributeExpression;
    }

    public ClassDescriptor getDescriptor(){
        return this.descriptor;
    }

    /**
     * INTERNAL:
     * Set the list of expressions that represent elements that are joined because of their
     * mapping for this query.
     */
    public JoinedAttributeManager getJoinedAttributeManager() {
        if (this.joinedAttributeManager == null) {
            this.joinedAttributeManager = new JoinedAttributeManager();
        }
        return this.joinedAttributeManager;
    }

    public JoinedAttributeManager getJoinedAttributeManagerInternal(){
        return joinedAttributeManager;
    }

    /**
     * INTERNAL:
     * Return if any attributes are joined.
     * To avoid the initialization of the JoinedAttributeManager this should be first checked before accessing.
     */
    public boolean hasJoining() {
        return this.joinedAttributeManager != null;
    }

    public DatabaseMapping getMapping() {
        return mapping;
    }

    public String getName() {
        return name;
    }

    public int getResultIndex() {
        return resultIndex;
    }

    public Class<?> getResultType() {
        return resultType;
    }

    /**
     * INTERNAL:
     * Looks up mapping for attribute during preExecute of ReportQuery
     */
    public void initialize(ReportQuery query) throws QueryException {
        if (this.mapping == null) {
            if (this.attributeExpression != null) {
                DatabaseMapping mapping = this.attributeExpression.getLeafMapping(query, query.getDescriptor(), query.getSession());
                if (mapping == null) {
                    //TODO: This feels like it should be set earlier during ReportItemBuild.visit. Should investigate.
                    if (this.attributeExpression.isExpressionBuilder()) {
                        Class<?> resultClass = ((ExpressionBuilder)this.attributeExpression).getQueryClass();
                        if (resultClass == null) {
                            resultClass = query.getReferenceClass();
                            ((ExpressionBuilder)this.attributeExpression).setQueryClass(resultClass);
                        }
                        setDescriptor(query.getSession().getDescriptor(resultClass));
                        if (getDescriptor().hasInheritance()) {
                            ((ExpressionBuilder)this.attributeExpression).setShouldUseOuterJoinForMultitableInheritance(true);
                        }
                    }
                } else {
                    if (mapping.isAbstractDirectMapping() || this.attributeExpression.isMapEntryExpression() || mapping.isAggregateObjectMapping() || mapping.isDirectCollectionMapping()){
                            setMapping(mapping);
                    //Bug4942640  Widen the check to support collection mapping too
                    } else if (mapping.isForeignReferenceMapping()) {
                        // DirectCollectionMapping doesn't have reference descriptor
                        if(mapping.getReferenceDescriptor() != null) {
                            setDescriptor(mapping.getReferenceDescriptor());
                            if (getDescriptor().hasInheritance()){
                                ((QueryKeyExpression)this.attributeExpression).setShouldUseOuterJoinForMultitableInheritance(true);
                            }
                        }
                    } else {
                        throw QueryException.invalidExpressionForQueryItem(this.attributeExpression, query);
                    }
                }
                if (hasJoining()) {
                    this.joinedAttributeManager.setDescriptor(this.descriptor);
                    this.joinedAttributeManager.setBaseQuery(query);
                }
                if (getAttributeExpression() != null){
                    if (getAttributeExpression().getBuilder().wasQueryClassSetInternally()){
                        //rebuild if class was not set by user this ensures the query has the same base
                        this.attributeExpression = this.attributeExpression.rebuildOn(query.getExpressionBuilder());
                    }
                    if (hasJoining()) {
                        this.joinedAttributeManager.setBaseExpressionBuilder(this.attributeExpression.getBuilder());
                    }
                } else if (hasJoining()) {
                    this.joinedAttributeManager.setBaseExpressionBuilder(query.getExpressionBuilder());
                }
                if (hasJoining()) {
                    this.joinedAttributeManager.prepareJoinExpressions(query.getSession());
                    this.joinedAttributeManager.processJoinedMappings(query.getSession());
                    this.joinedAttributeManager.computeJoiningMappingQueries(query.getSession());
                }
            }
        }
    }

    public boolean isConstructorItem(){
        return false;
    }

    public void setDescriptor(ClassDescriptor descriptor){
        this.descriptor = descriptor;
    }


    public void setJoinedAttributeManager(JoinedAttributeManager joinManager){
        this.joinedAttributeManager = joinManager;
    }

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

    public void setResultIndex(int resultIndex) {
        this.resultIndex = resultIndex;
        if (hasJoining()) {
            getJoinedAttributeManager().setParentResultIndex(resultIndex);
        }
    }

    public void setResultType(Class<?> resultType) {
        this.resultType = resultType;

        // Set it on the attribute expression as well if it is a function.
        if (getAttributeExpression()!=null && getAttributeExpression().isFunctionExpression()) {
            ((FunctionExpression) getAttributeExpression()).setResultType(resultType);
        }
    }

    @Override
    public String toString() {
        return "ReportQueryItem(" + getName() + " -> " + getAttributeExpression() + ")";
    }
}
