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

    /**
     * {@inheritDoc}
     */
    @Override
    public T abs(T builder) {

        checkBuilder(builder);

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

    /**
     * {@inheritDoc}
     */
    @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);
    }

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

    /**
     * {@inheritDoc}
     */
    @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);
    }

    /**
     * {@inheritDoc}
     */
    @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;
    }

    /**
     * {@inheritDoc}
     */
    @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;
    }

    /**
     * {@inheritDoc}
     */
    @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);
    }

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

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

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

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

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

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

    /**
     * {@inheritDoc}
     */
    @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;
    }

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

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

    /**
     * {@inheritDoc}
     */
    @Override
    public T function(String identifier, String functionName, String... arguments) {

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

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

    /**
     * {@inheritDoc}
     */
    @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;
    }

    /**
     * {@inheritDoc}
     */
    @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;
    }

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

    /**
     * {@inheritDoc}
     */
    @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;
    }

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

    /**
     * {@inheritDoc}
     */
    @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);
    }

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

    /**
     * {@inheritDoc}
     */
    @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);
    }

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

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

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

    /**
     * {@inheritDoc}
     */
    @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;
    }

    /**
     * {@inheritDoc}
     */
    @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;
    }

    /**
     * {@inheritDoc}
     */
    @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;
    }

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

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

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

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

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

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

    /**
     * {@inheritDoc}
     */
    @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);
    }

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

    /**
     * {@inheritDoc}
     */
    @Override
    public T sub(T builder) {

        checkBuilders(builder);

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

    /**
     * {@inheritDoc}
     */
    @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);
    }

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

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

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