/*
 * 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.lang.reflect.Array;
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) {
        return coalesce(builder1, builder2, (T[]) Array.newInstance(builder1.getClass(), 0));
    }

    @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) {
        return concat(builder1, builder2, (T[]) Array.newInstance(builder1.getClass(), 0));
    }

    @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) {
        StateObject stateObject = new FunctionExpressionStateObject(
                getParent(),
                identifier,
                functionName,
                stateObjects(0)
        );

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