/*
 * Copyright (c) 2006, 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
//
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;
    }

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

    @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]);
    }

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

    @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]);
    }

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

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

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

    @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;
        }
    }

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

    @Override
    public void visit(ConstructorExpression expression) {

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

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

    @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]);
    }

    @Override
    public void visit(DateTime expression) {

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

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

    @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]);
    }

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

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

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

    @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);
        }
    }

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

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

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

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

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

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

    @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]);
    }

    @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]);
    }

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

    @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]);
    }

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

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

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

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

    @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;
    }

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

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

    @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);
    }

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

    @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();
    }

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

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

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

    @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]);
    }

    @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]);
    }

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

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

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

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

    @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 {

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

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

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