/*
 * Copyright (c) 2011, 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
//
package org.eclipse.persistence.jpa.jpql.tools.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.persistence.jpa.jpql.Assert;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AbsExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AdditionExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ArithmeticFactorStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AvgFunctionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CoalesceExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CollectionValuedPathExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ConcatExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CountFunctionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.DateTimeStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.DivisionExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.EntityTypeLiteralStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.EnumTypeStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.FunctionExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.IdentificationVariableStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.IndexExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.InputParameterStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.LengthExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.LocateExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.MaxFunctionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ModExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.MultiplicationExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.NullIfExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.NumericLiteralStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SizeExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SqrtExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.StateFieldPathExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.StateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.StringLiteralStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SubExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SubtractionExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SumFunctionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.TypeExpressionStateObject;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.*;

/**
 * This abstract definition of a builder provides the support for creating expressions defined by a
 * <code>scalar expression</code>.
 *
 * @version 2.4
 * @since 2.4
 * @author Pascal Filion
 */
@SuppressWarnings({"unchecked", "nls"})
public abstract class AbstractScalarExpressionStateObjectBuilder<T extends IScalarExpressionStateObjectBuilder<T>> extends AbstractStateObjectBuilder
    implements IScalarExpressionStateObjectBuilder<T> {

    /**
     * Caches the {@link ICaseExpressionStateObjectBuilder} while it's been used.
     */
    private ICaseExpressionStateObjectBuilder caseBuilder;

    /**
     * The parent of the expression to build, which is only required when a JPQL fragment needs to
     * be parsed.
     */
    private StateObject parent;

    /**
     * Creates a new <code>AbstractScalarExpressionStateObjectBuilder</code>.
     *
     * @param parent The parent of the expression to build, which is only required when a JPQL
     * fragment needs to be parsed
     */
    protected AbstractScalarExpressionStateObjectBuilder(StateObject parent) {
        super();
        this.parent = parent;
    }

    @Override
    public T abs(T builder) {

        checkBuilder(builder);

        StateObject stateObject = new AbsExpressionStateObject(parent, pop());
        add(stateObject);
        return (T) this;
    }

    @Override
    public T add(T builder) {

        checkBuilder(builder);

        StateObject rightStateObject = pop();
        StateObject leftStateObject  = pop();

        StateObject stateObject = new AdditionExpressionStateObject(
            parent,
            leftStateObject,
            rightStateObject
        );

        add(stateObject);
        return (T) this;
    }

    protected void arithmetic(boolean plusSign) {
        StateObject stateObject = new ArithmeticFactorStateObject(parent, plusSign, pop());
        add(stateObject);
    }

    protected void avg(boolean distinct, String path) {
        StateObject stateObject = new AvgFunctionStateObject(parent, distinct, literal(path));
        add(stateObject);
    }

    @Override
    public T avg(String path) {
        avg(false, path);
        return (T) this;
    }

    @Override
    public T avgDistinct(String path) {
        avg(true, path);
        return (T) this;
    }

    protected StateObject buildCollectionPath(String path) {
        return new CollectionValuedPathExpressionStateObject(parent, path);
    }

    protected StateObject buildIdentificationVariable(String literal) {
        return new IdentificationVariableStateObject(parent, literal);
    }

    protected StateObject buildInputParameter(String parameter) {
        return new InputParameterStateObject(parent, parameter);
    }

    protected StateObject buildNumeric(Number number) {
        return new NumericLiteralStateObject(parent, number);
    }

    protected StateObject buildNumeric(String number) {
        return new NumericLiteralStateObject(parent, number);
    }

    protected StateObject buildStateFieldPath(String path) {
        return new StateFieldPathExpressionStateObject(parent, path);
    }

    protected StateObject buildStringLiteral(String literal) {
        return new StringLiteralStateObject(parent, literal);
    }

    @Override
    public T case_(ICaseExpressionStateObjectBuilder builder) {
        Assert.isEqual(caseBuilder, builder, "The Case expression builder is not the same as the current one");
        add(builder.buildStateObject());
        builder = null;
        return (T) this;
    }

    @Override
    public T coalesce(T builder1, T builder2, T... builders) {

        checkBuilders(builder1, builder2);
        checkBuilders(builders);

        List<StateObject> stateObjects = new ArrayList<StateObject>();
        stateObjects.addAll(stateObjects(builders));
        stateObjects.add(0, pop());
        stateObjects.add(0, pop());

        StateObject stateObject = new CoalesceExpressionStateObject(parent, stateObjects);
        add(stateObject);
        return (T) this;
    }

    @Override
    public T concat(T builder1, T builder2, T... builders) {

        checkBuilders(builder1, builder2);
        checkBuilders(builders);

        List<StateObject> stateObjects = new ArrayList<StateObject>();
        stateObjects.addAll(stateObjects(builders));
        stateObjects.add(0, pop());
        stateObjects.add(0, pop());

        StateObject stateObject = new ConcatExpressionStateObject(parent, stateObjects);
        add(stateObject);
        return (T) this;
    }

    protected void count(boolean distinct, String path) {
        StateObject stateObject = new CountFunctionStateObject(parent, distinct, literal(path));
        add(stateObject);
    }

    @Override
    public T count(String path) {
        count(false, path);
        return (T) this;
    }

    @Override
    public T countDistinct(String path) {
        count(true, path);
        return (T) this;
    }

    @Override
    public T currentDate() {
        return date(CURRENT_DATE);
    }

    @Override
    public T currentTime() {
        return date(CURRENT_TIME);
    }

    @Override
    public T currentTimestamp() {
        return date(CURRENT_TIMESTAMP);
    }

    @Override
    public T date(String jdbcDate) {
        StateObject stateObject = new DateTimeStateObject(parent, jdbcDate);
        add(stateObject);
        return (T) this;
    }

    @Override
    public T divide(T builder) {

        checkBuilder(builder);

        StateObject rightStateObject = pop();
        StateObject leftStateObject  = pop();

        StateObject stateObject = new DivisionExpressionStateObject(
            parent,
            leftStateObject,
            rightStateObject
        );

        add(stateObject);
        return (T) this;
    }

    @Override
    public T entityType(String entityTypeName) {
        StateObject stateObject = new EntityTypeLiteralStateObject(parent,entityTypeName);
        add(stateObject);
        return (T) this;
    }

    @Override
    public T enumLiteral(Enum<? extends Enum<?>> enumConstant) {
        StateObject stateObject = new EnumTypeStateObject(parent, enumConstant);
        add(stateObject);
        return (T) this;
    }

    @Override
    public T function(String identifier, String functionName, String... arguments) {

        StateObject stateObject = new FunctionExpressionStateObject(
            getParent(),
            identifier,
            functionName,
            literals(arguments)
        );

        add(stateObject);
        return (T) this;
    }

    @Override
    public T function(String identifier, String functionName, T... arguments) {

        checkBuilders(arguments);

        StateObject stateObject = new FunctionExpressionStateObject(
            getParent(),
            identifier,
            functionName,
            stateObjects(arguments)
        );

        add(stateObject);
        return (T) this;
    }

    @Override
    public ICaseExpressionStateObjectBuilder getCaseBuilder() {
        if (caseBuilder == null) {
            caseBuilder = getParent().getQueryBuilder().buildCaseExpressionStateObjectBuilder(parent);
        }
        return caseBuilder;
    }

    /**
     * Returns the parent of the expression to build, which is only required when a JPQL fragment
     * needs to be parsed.
     *
     * @return The parent
     */
    protected StateObject getParent() {
        return parent;
    }

    @Override
    public T index(String variable) {
        StateObject stateObject = new IndexExpressionStateObject(parent, variable);
        add(stateObject);
        return (T) this;
    }

    @Override
    public T length(T builder) {

        checkBuilder(builder);

        StateObject stateObject = new LengthExpressionStateObject(parent, pop());
        add(stateObject);
        return (T) this;
    }

    protected StateObject literal(String literal) {

        if ((literal != null) && (literal.length() > 0)) {

            char character = literal.charAt(0);

            // String literal
            if (ExpressionTools.isQuote(character)) {
                return buildStringLiteral(literal);
            }

            // Input parameter
            if (ExpressionTools.isParameter(character)) {
                return buildInputParameter(literal);
            }

            // State-field path expression
            if (literal.indexOf('.') > 0) {
                return buildStateFieldPath(literal);
            }

            // Identification variable
            return buildIdentificationVariable(literal);
        }

        // String literal
        return buildStringLiteral(literal);
    }

    protected List<StateObject> literals(String... literals) {
        List<StateObject> stateObjects = new ArrayList<StateObject>();
        for (String literal : literals) {
            stateObjects.add(literal(literal));
        }
        return stateObjects;
    }

    @Override
    public T locate(T parameter1, T parameter2) {
        return locate(parameter1, parameter2, null);
    }

    @Override
    public T locate(T parameter1, T parameter2, T parameter3) {

        checkBuilders(parameter1, parameter2);

        if (parameter3 != null) {
            checkBuilder(parameter3);
        }

        StateObject thirdStateObject  = (parameter3 != null) ? pop() : null;
        StateObject secondStateObject = pop();
        StateObject firstStateObject  = pop();

        StateObject stateObject = new LocateExpressionStateObject(
            parent,
            firstStateObject,
            secondStateObject,
            thirdStateObject
        );

        add(stateObject);
        return (T) this;
    }

    protected void max(boolean distinct, String path) {
        StateObject stateObject = new MaxFunctionStateObject(parent, distinct, literal(path));
        add(stateObject);
    }

    @Override
    public T max(String path) {
        max(false, path);
        return (T) this;
    }

    @Override
    public T maxDistinct(String path) {
        max(true, path);
        return (T) this;
    }

    protected void min(boolean distinct, String path) {
        StateObject stateObject = new MaxFunctionStateObject(parent, distinct, literal(path));
        add(stateObject);
    }

    @Override
    public T min(String path) {
        min(false, path);
        return (T) this;
    }

    @Override
    public T minDistinct(String path) {
        min(true, path);
        return (T) this;
    }

    @Override
    public T minus(T builder) {
        checkBuilders(builder);
        arithmetic(false);
        return (T) this;
    }

    @Override
    public T mod(T parameter1, T parameter2) {

        checkBuilders(parameter1, parameter2);

        StateObject secondStateObject = pop();
        StateObject firstStateObject  = pop();

        StateObject stateObject = new ModExpressionStateObject(
            parent,
            firstStateObject,
            secondStateObject
        );

        add(stateObject);
        return (T) this;
    }

    @Override
    public T multiply(T builder) {

        checkBuilders(builder);

        StateObject rightStateObject = pop();
        StateObject leftStateObject  = pop();

        StateObject stateObject = new MultiplicationExpressionStateObject(
            parent,
            leftStateObject,
            rightStateObject
        );

        add(stateObject);
        return (T) this;
    }

    @Override
    public T nullIf(T builder1, T builder2) {

        checkBuilders(builder1, builder2);

        StateObject rightStateObject = pop();
        StateObject leftStateObject  = pop();

        StateObject stateObject = new NullIfExpressionStateObject(
            parent,
            leftStateObject,
            rightStateObject
        );

        add(stateObject);
        return (T) this;
    }

    @Override
    public T numeric(Number number) {
        StateObject stateObject = buildNumeric(number);
        add(stateObject);
        return (T) this;
    }

    @Override
    public T numeric(String number) {
        StateObject stateObject = buildNumeric(number);
        add(stateObject);
        return (T) this;
    }

    @Override
    public T parameter(String parameter) {
        StateObject stateObject = buildInputParameter(parameter);
        add(stateObject);
        return (T) this;
    }

    @Override
    public T path(String path) {
        StateObject stateObject = buildStateFieldPath(path);
        add(stateObject);
        return (T) this;
    }

    @Override
    public T plus(T builder) {
        checkBuilders(builder);
        arithmetic(true);
        return (T) this;
    }

    @Override
    public T size(String path) {
        StateObject stateObject = new SizeExpressionStateObject(parent, buildCollectionPath(path));
        add(stateObject);
        return (T) this;
    }

    @Override
    public T sqrt(T builder) {

        checkBuilders(builder);

        StateObject stateObject = new SqrtExpressionStateObject(parent, pop());
        add(stateObject);
        return (T) this;
    }

    /**
     * Returns a list of the {@link StateObject StateObjects} that were previously created.
     *
     * @param count The number of {@link StateObject StateObjects} to move to the list
     * @return The list of {@link StateObject StateObjects} that were added to the stack
     */
    protected List<StateObject> stateObjects(int count) {

        if (count == 0) {
            return Collections.emptyList();
        }

        List<StateObject> items = new ArrayList<StateObject>(count);

        while (count-- > 0) {
            items.add(0, pop());
        }

        return items;
    }

    /**
     * Returns a list of the {@link StateObject StateObjects} that were previously created.
     *
     * @param builders The list of {@link IScalarExpressionStateObjectBuilder builders} is used to
     * determine how many {@link StateObject StateObjects} needs to be pulled out of the stack
     * @return The list of {@link StateObject StateObjects} that were added to the stack
     */
    protected List<StateObject> stateObjects(T... builders) {
        return stateObjects(builders.length);
    }

    @Override
    public T string(String literal) {
        StateObject stateObject = buildStringLiteral(literal);
        add(stateObject);
        return (T) this;
    }

    @Override
    public T sub(T builder) {

        checkBuilders(builder);

        StateObject stateObject = new SubExpressionStateObject(parent, pop());
        add(stateObject);
        return (T) this;
    }

    @Override
    public T subtract(T builder) {

        checkBuilders(builder);

        StateObject rightStateObject = pop();
        StateObject leftStateObject  = pop();

        StateObject stateObject = new SubtractionExpressionStateObject(
            parent,
            leftStateObject,
            rightStateObject
        );

        add(stateObject);
        return (T) this;
    }

    protected void sum(boolean distinct, String path) {
        StateObject stateObject = new SumFunctionStateObject(parent, distinct, literal(path));
        add(stateObject);
    }

    @Override
    public T sum(String path) {
        sum(false, path);
        return (T) this;
    }

    @Override
    public T sumDistinct(String path) {
        sum(true, path);
        return (T) this;
    }

    @Override
    public T type(String path) {
        StateObject stateObject = new TypeExpressionStateObject(parent, path);
        add(stateObject);
        return (T) this;
    }
}
