/*
 * Copyright (c) 2006, 2019 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
//
package org.eclipse.persistence.internal.jpa.jpql;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.parser.AbsExpression;
import org.eclipse.persistence.jpa.jpql.parser.AbstractSelectClause;
import org.eclipse.persistence.jpa.jpql.parser.AdditionExpression;
import org.eclipse.persistence.jpa.jpql.parser.ArithmeticFactor;
import org.eclipse.persistence.jpa.jpql.parser.AvgFunction;
import org.eclipse.persistence.jpa.jpql.parser.CaseExpression;
import org.eclipse.persistence.jpa.jpql.parser.CastExpression;
import org.eclipse.persistence.jpa.jpql.parser.CoalesceExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionValuedPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConcatExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConstructorExpression;
import org.eclipse.persistence.jpa.jpql.parser.CountFunction;
import org.eclipse.persistence.jpa.jpql.parser.DateTime;
import org.eclipse.persistence.jpa.jpql.parser.DivisionExpression;
import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkAnonymousExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.EntryExpression;
import org.eclipse.persistence.jpa.jpql.parser.ExtractExpression;
import org.eclipse.persistence.jpa.jpql.parser.FunctionExpression;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable;
import org.eclipse.persistence.jpa.jpql.parser.IndexExpression;
import org.eclipse.persistence.jpa.jpql.parser.Join;
import org.eclipse.persistence.jpa.jpql.parser.KeyExpression;
import org.eclipse.persistence.jpa.jpql.parser.KeywordExpression;
import org.eclipse.persistence.jpa.jpql.parser.LengthExpression;
import org.eclipse.persistence.jpa.jpql.parser.LocateExpression;
import org.eclipse.persistence.jpa.jpql.parser.LowerExpression;
import org.eclipse.persistence.jpa.jpql.parser.MaxFunction;
import org.eclipse.persistence.jpa.jpql.parser.MinFunction;
import org.eclipse.persistence.jpa.jpql.parser.ModExpression;
import org.eclipse.persistence.jpa.jpql.parser.MultiplicationExpression;
import org.eclipse.persistence.jpa.jpql.parser.NullIfExpression;
import org.eclipse.persistence.jpa.jpql.parser.NumericLiteral;
import org.eclipse.persistence.jpa.jpql.parser.ObjectExpression;
import org.eclipse.persistence.jpa.jpql.parser.ResultVariable;
import org.eclipse.persistence.jpa.jpql.parser.SelectClause;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectClause;
import org.eclipse.persistence.jpa.jpql.parser.SizeExpression;
import org.eclipse.persistence.jpa.jpql.parser.SqrtExpression;
import org.eclipse.persistence.jpa.jpql.parser.StateFieldPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.StringLiteral;
import org.eclipse.persistence.jpa.jpql.parser.SubExpression;
import org.eclipse.persistence.jpa.jpql.parser.SubstringExpression;
import org.eclipse.persistence.jpa.jpql.parser.SubtractionExpression;
import org.eclipse.persistence.jpa.jpql.parser.SumFunction;
import org.eclipse.persistence.jpa.jpql.parser.TreatExpression;
import org.eclipse.persistence.jpa.jpql.parser.TrimExpression;
import org.eclipse.persistence.jpa.jpql.parser.TypeExpression;
import org.eclipse.persistence.jpa.jpql.parser.UpperExpression;
import org.eclipse.persistence.jpa.jpql.parser.ValueExpression;
import org.eclipse.persistence.queries.ReportQuery;

import static org.eclipse.persistence.jpa.jpql.LiteralType.*;

/**
 * This builder is responsible to create the EclipseLink {@link Expression Expressions} representing
 * the select items of the <code><b>SELECT</b></code> clause.
 *
 * @version 2.4
 * @since 2.3
 * @author Pascal Filion
 * @author John Bracken
 */
@SuppressWarnings("nls")
final class ReportItemBuilder extends EclipseLinkAnonymousExpressionVisitor {

    /**
     * The visitor responsible to visit the constructor items.
     */
    private ConstructorExpressionVisitor constructorExpressionVisitor;

    /**
     * Determines whether the <code><b>SELECT</b></code> clause has more than one select item.
     */
    private boolean multipleSelects;

    /**
     * The {@link ReportQuery} to add the select expressions.
     */
    private ReportQuery query;

    /**
     * The {@link JPQLQueryContext} is used to query information about the application metadata and
     * cached information.
     */
    private final JPQLQueryContext queryContext;

    /**
     * If the select expression is aliased with a result variable, then temporarily cache it so it
     * can be used as the attribute name.
     */
    private String resultVariable;

    /**
     * This array is used to store the type of the select {@link Expression JPQL Expression} that is
     * converted into an {@link Expression EclipseLink Expression}.
     */
    final Class<?>[] type;

    /**
     * Creates a new <code>ReportItemBuilder</code>.
     *
     * @param queryContext The context used to query information about the application metadata and
     * cached information
     * @param query The {@link ReportQuery} to populate by using this visitor to visit the parsed
     * tree representation of the JPQL query
     */
    ReportItemBuilder(JPQLQueryContext queryContext, ReportQuery query) {
        super();
        this.query        = query;
        this.type         = new Class<?>[1];
        this.queryContext = queryContext;
    }

    private void addAttribute(String generateName, Expression queryExpression) {

        if (resultVariable != null) {
            generateName = resultVariable;
            queryContext.addQueryExpression(resultVariable.toUpperCase(), queryExpression);
        }

        query.addAttribute(generateName, queryExpression);
    }

    private void addAttribute(String generateName, Expression queryExpression, Class<?> type) {

        if (resultVariable != null) {
            generateName = resultVariable;
            queryContext.addQueryExpression(resultVariable.toUpperCase(), queryExpression);
        }

        query.addAttribute(generateName, queryExpression, type);
    }

    private ConstructorExpressionVisitor constructorExpressionVisitor() {
        if (constructorExpressionVisitor == null) {
            constructorExpressionVisitor = new ConstructorExpressionVisitor();
        }
        return constructorExpressionVisitor;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(AbsExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(ExpressionTools.EMPTY_STRING, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(AdditionExpression expression) {

        Expression queryExpression = queryContext.buildExpression(expression, type);

        if (type[0] == Object.class) {
            type[0] = null;
        }

        addAttribute("plus", queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ArithmeticFactor expression) {
        // TODO: Anything to do other than the default behavior?
        super.visit(expression);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(AvgFunction expression) {
        String name = queryContext.literal(expression.getExpression(), PATH_EXPRESSION_LAST_PATH);
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(name, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(CaseExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute("Case", queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(CastExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(ExpressionTools.EMPTY_STRING, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(CoalesceExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute("Coalesce", queryExpression);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(CollectionExpression expression) {

        multipleSelects = true;

        for (org.eclipse.persistence.jpa.jpql.parser.Expression child : expression.children()) {
            child.accept(this);
            type[0] = null;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ConcatExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(ExpressionTools.EMPTY_STRING, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ConstructorExpression expression) {

        Class<?> type = queryContext.getType(expression.getClassName());

        query.beginAddingConstructorArguments(type);
        expression.accept(constructorExpressionVisitor());
        query.endAddingToConstructorItem();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(CountFunction expression) {

        // Retrieve the attribute name
        String name = queryContext.literal(expression.getExpression(), PATH_EXPRESSION_LAST_PATH);

        if (name == ExpressionTools.EMPTY_STRING) {
            name = CountFunction.COUNT;
        }

        // Add the attribute
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(name, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(DateTime expression) {

        Expression queryExpression = queryContext.buildExpression(expression, type);

        if (expression.isJDBCDate()) {
            addAttribute("CONSTANT", queryExpression);
        }
        else {
            addAttribute("date", queryExpression, type[0]);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(DivisionExpression expression) {

        Expression queryExpression = queryContext.buildExpression(expression, type);

        if (type[0] == Object.class) {
            type[0] = null;
        }

        addAttribute("divide", queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(EntryExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(" MapEntry", queryExpression);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ExtractExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(ExpressionTools.EMPTY_STRING, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(FunctionExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(ExpressionTools.EMPTY_STRING, queryExpression);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(IdentificationVariable expression) {

        String variableName = expression.getVariableName();

        // Retrieve the FETCH JOIN expressions using the identification variable
        List<org.eclipse.persistence.expressions.Expression> joinFetchExpressions = null;

        // Retrieve the join fetches that were defined in the same identification variable
        // declaration, if the identification variable is mapped to a join, then there will
        // not be any join fetch associated with it
        Collection<Join> joinFetches = queryContext.getJoinFetches(variableName);

        if (joinFetches != null) {

            for (Join joinFetch : joinFetches) {

                // Retrieve the join association path expression's identification variable
                String joinFetchVariableName = queryContext.literal(
                    joinFetch,
                    PATH_EXPRESSION_IDENTIFICATION_VARIABLE
                );

                if (variableName.equals(joinFetchVariableName)) {
                    if (joinFetchExpressions == null) {
                        joinFetchExpressions = new ArrayList<>();
                    }
                    joinFetchExpressions.add(queryContext.buildExpression(joinFetch, type));
                }
            }
        }

        Expression queryExpression = queryContext.buildExpression(expression, type);

        // Add the attribute without any JOIN FETCH
        if (joinFetchExpressions == null) {
            query.addAttribute(expression.getText(), queryExpression);
        }
        // Add the attribute with the JOIN FETCH expressions
        else {
            query.addItem(expression.getText(), queryExpression, joinFetchExpressions);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(IndexExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute("Index", queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(KeyExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute("MapKey", queryExpression);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(KeywordExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute("CONSTANT", queryExpression);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(LengthExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(ExpressionTools.EMPTY_STRING, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(LocateExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(ExpressionTools.EMPTY_STRING, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(LowerExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(ExpressionTools.EMPTY_STRING, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(MaxFunction expression) {
        String name = queryContext.literal(expression.getExpression(), PATH_EXPRESSION_LAST_PATH);
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(name, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(MinFunction expression) {
        String name = queryContext.literal(expression.getExpression(), PATH_EXPRESSION_LAST_PATH);
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(name, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ModExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(ExpressionTools.EMPTY_STRING, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(MultiplicationExpression expression) {

        Expression queryExpression = queryContext.buildExpression(expression, type);

        if (type[0] == Object.class) {
            type[0] = null;
        }

        addAttribute("multiply", queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(NullIfExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(NullIfExpression.NULLIF, queryExpression);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(NumericLiteral expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute("CONSTANT", queryExpression);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ObjectExpression expression) {
        expression.getExpression().accept(this);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void visit(org.eclipse.persistence.jpa.jpql.parser.Expression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(ExpressionTools.EMPTY_STRING, queryExpression);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ResultVariable expression) {

        // Now cache the Expression for future retrieval by the ORDER BY clause
        IdentificationVariable identificationVariable = (IdentificationVariable) expression.getResultVariable();
        resultVariable = identificationVariable.getText();

        // Create the Expression that is added to the query as an attribute
        expression.getSelectExpression().accept(this);

        resultVariable = null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SelectClause expression) {
        visitAbstractSelectClause(expression);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SimpleSelectClause expression) {
        visitAbstractSelectClause(expression);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SizeExpression expression) {

        // Add the attribute
        Expression queryExpression = queryContext.buildExpression(expression.getExpression());
        addAttribute("size", queryExpression.count(), Integer.class);

        // Now add the GROUP BY expression
        CollectionValuedPathExpression pathExpression = (CollectionValuedPathExpression) expression.getExpression();
        queryExpression = queryContext.buildGroupByExpression(pathExpression);
        query.addGrouping(queryExpression);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SqrtExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(ExpressionTools.EMPTY_STRING, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(StateFieldPathExpression expression) {

        // Temporarily change the null allowed flag if the state field is a foreign reference mapping
        Expression queryExpression = queryContext.buildModifiedPathExpression(expression);

        // Register the EclipseLink Expression with the state field name
        String name = expression.getPath(expression.pathSize() - 1);
        addAttribute(name, queryExpression);
        query.dontRetrievePrimaryKeys();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(StringLiteral expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute("CONSTANT", queryExpression);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SubExpression expression) {
        expression.getExpression().accept(this);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SubstringExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(ExpressionTools.EMPTY_STRING, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SubtractionExpression expression) {

        Expression queryExpression = queryContext.buildExpression(expression, type);

        if (type[0] == Object.class) {
            type[0] = null;
        }

        addAttribute("minus", queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SumFunction expression) {
        String name = queryContext.literal(expression.getExpression(), PATH_EXPRESSION_LAST_PATH);
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(name, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(TreatExpression expression) {
        // Nothing to do
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(TrimExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(ExpressionTools.EMPTY_STRING, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(TypeExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(ExpressionTools.EMPTY_STRING, queryExpression);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(UpperExpression expression) {
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(ExpressionTools.EMPTY_STRING, queryExpression, type[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ValueExpression expression) {
        IdentificationVariable identificationVariable = (IdentificationVariable) expression.getExpression();
        Expression queryExpression = queryContext.buildExpression(expression, type);
        addAttribute(identificationVariable.getText(), queryExpression);
    }

    private void visitAbstractSelectClause(AbstractSelectClause expression) {

        multipleSelects = false;
        expression.getSelectExpression().accept(this);

        if (multipleSelects) {
            query.returnWithoutReportQueryResult();
        }
        else {
            query.returnSingleAttribute();
        }
    }

    /**
     * This visitor takes care of creating the {@link org.eclipse.persistence.expressions.Expression
     * expressions} for the constructor arguments.
     */
    private class ConstructorExpressionVisitor extends EclipseLinkAnonymousExpressionVisitor {

        /**
         * {@inheritDoc}
         */
        @Override
        public void visit(CollectionExpression expression) {
            expression.acceptChildren(this);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void visit(ConstructorExpression expression) {
            expression.getConstructorItems().accept(this);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected void visit(org.eclipse.persistence.jpa.jpql.parser.Expression expression) {
            expression.accept(ReportItemBuilder.this);
        }
    }
}
