/*
 * 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.Collections;
import java.util.List;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.parser.TrimExpression.Specification;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AllOrAnyExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AndExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.BetweenExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CollectionMemberExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ComparisonExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.EmptyCollectionComparisonExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ExistsExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.InExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.KeywordExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.LikeExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.LowerExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.NullComparisonExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.OrExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SimpleSelectStatementStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.StateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SubExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SubstringExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.TrimExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.UpperExpressionStateObject;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.*;

/**
 * The abstract implementation of {@link IConditionalExpressionStateObjectBuilder} that supports the
 * creation of the conditional expression based on the JPQL grammar defined in JPA 2.0.
 *
 * @version 2.4
 * @since 2.4
 * @author Pascal Filion
 */
@SuppressWarnings("unchecked")
public abstract class AbstractConditionalExpressionStateObjectBuilder<T extends IAbstractConditionalExpressionStateObjectBuilder<T>>
    extends AbstractScalarExpressionStateObjectBuilder<T>
   implements IAbstractConditionalExpressionStateObjectBuilder<T> {

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

    @Override
    public T all(SimpleSelectStatementStateObject subquery) {
        allOrAny(ALL, subquery);
        return (T) this;
    }

    protected void allOrAny(String identifier, SimpleSelectStatementStateObject subquery) {
        StateObject stateObject = new AllOrAnyExpressionStateObject(getParent(), identifier, subquery);
        add(stateObject);
    }

    @Override
    public T and(T builder) {

        checkBuilder(builder);

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

        StateObject stateObject = new AndExpressionStateObject(
            getParent(),
            leftStateObject,
            rightStateObject
        );

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

    @Override
    public T any(SimpleSelectStatementStateObject subquery) {
        allOrAny(ANY, subquery);
        return (T) this;
    }

    protected void between(boolean not) {

        StateObject upperBoundStateObject  = pop();
        StateObject lowerBoundStateObject  = pop();
        StateObject firstStateObject       = pop();

        StateObject stateObject = new BetweenExpressionStateObject(
            getParent(),
            firstStateObject,
            not,
            lowerBoundStateObject,
            upperBoundStateObject
        );

        add(stateObject);
    }

    @Override
    public T between(T lowerBoundExpression, T upperBoundExpression) {
        checkBuilders(lowerBoundExpression, upperBoundExpression);
        between(false);
        return (T) this;
    }

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

    protected void comparison(String identifier) {
        comparison(identifier, pop());
    }

    protected void comparison(String identifier, StateObject rightStateObject) {

        StateObject leftStateObject = pop();

        StateObject stateObject = new ComparisonExpressionStateObject(
            getParent(),
            leftStateObject,
            identifier,
            rightStateObject
        );

        add(stateObject);
    }

    @Override
    public T different(Number number) {
        comparison(DIFFERENT, buildNumeric(number));
        return (T) this;
    }

    @Override
    public T different(String literal) {
        comparison(DIFFERENT, literal(literal));
        return (T) this;
    }

    @Override
    public T different(T builder) {
        checkBuilder(builder);
        comparison(DIFFERENT);
        return (T) this;
    }

    @Override
    public T equal(Number number) {
        comparison(EQUAL, buildNumeric(number));
        return (T) this;
    }

    @Override
    public T equal(String literal) {
        comparison(EQUAL, literal(literal));
        return (T) this;
    }

    @Override
    public T equal(T builder) {
        checkBuilder(builder);
        comparison(EQUAL);
        return (T) this;
    }

    protected void exists(boolean not, SimpleSelectStatementStateObject subquery) {
        StateObject stateObject = new ExistsExpressionStateObject(getParent(), not, subquery);
        add(stateObject);
    }

    @Override
    public T exists(SimpleSelectStatementStateObject subquery) {
        exists(false, subquery);
        return (T) this;
    }

    @Override
    public T FALSE() {
        keyword(FALSE);
        return (T) this;
    }

    @Override
    public T greaterThan(Number number) {
        comparison(GREATER_THAN, buildNumeric(number));
        return (T) this;
    }

    @Override
    public T greaterThan(String literal) {
        comparison(GREATER_THAN, literal(literal));
        return (T) this;
    }

    @Override
    public T greaterThan(T builder) {
        checkBuilder(builder);
        comparison(GREATER_THAN);
        return (T) this;
    }

    @Override
    public T greaterThanOrEqual(Number number) {
        comparison(GREATER_THAN_OR_EQUAL, buildNumeric(number));
        return (T) this;
    }

    @Override
    public T greaterThanOrEqual(String literal) {
        comparison(GREATER_THAN_OR_EQUAL, literal(literal));
        return (T) this;
    }

    @Override
    public T greaterThanOrEqual(T builder) {
        checkBuilder(builder);
        comparison(GREATER_THAN_OR_EQUAL);
        return (T) this;
    }

    protected void in(boolean not, List<StateObject> inItems) {

        StateObject stateFieldPath = pop();

        StateObject stateObject = new InExpressionStateObject(
            getParent(),
            stateFieldPath,
            not,
            inItems
        );

        add(stateObject);
    }

    protected void in(boolean not, String... inItems) {
        in(not, literals(inItems));
    }

    protected void in(boolean not, T... inItems) {
        in(false, stateObjects(inItems));
    }

    @Override
    public T in(SimpleSelectStatementStateObject subquery) {
        in(false, Collections.<StateObject>singletonList(subquery));
        return (T) this;
    }

    @Override
    public T in(String... inItems) {
        in(false, inItems);
        return (T) this;
    }

    @Override
    public T in(T... inItems) {
        checkBuilders(inItems);
        in(false, inItems);
        return (T) this;
    }

    protected void isEmpty(boolean not, String path) {

        StateObject stateObject = new EmptyCollectionComparisonExpressionStateObject(
            getParent(),
            not,
            path
        );

        add(stateObject);
    }

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

    @Override
    public T isNotEmpty(String path) {
        isEmpty(true, path);
        return (T) this;
    }

    @Override
    public T isNotNull(String path) {
        isNull(true, path);
        return (T) this;
    }

    protected void isNull(boolean not, String path) {

        StateObject stateObject;

        if (ExpressionTools.isParameter(path.charAt(0))) {
            stateObject = buildInputParameter(path);
        }
        else {
            stateObject = buildStateFieldPath(path);
        }

        stateObject = new NullComparisonExpressionStateObject(
            getParent(),
            not,
            stateObject
        );

        add(stateObject);
    }

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

    protected void keyword(String identifier) {
        StateObject stateObject = new KeywordExpressionStateObject(getParent(), identifier);
        add(stateObject);
    }

    protected void like(boolean not, String escapeCharacter) {

        StateObject patternValue = pop();
        StateObject string       = pop();

        StateObject stateObject = new LikeExpressionStateObject(
            getParent(),
            string,
            not,
            patternValue,
            escapeCharacter
        );

        add(stateObject);
    }

    @Override
    public T like(String patternValue) {
        like(string(patternValue));
        return (T) this;
    }

    @Override
    public T like(T patternValue) {
        checkBuilder(patternValue);
        like(false, null);
        return (T) this;
    }

    @Override
    public T like(T patternValue, String escapeCharacter) {
        checkBuilder(patternValue);
        like(false, escapeCharacter);
        return (T) this;
    }

    @Override
    public T lower(T builder) {
        checkBuilder(builder);
        StateObject stateObject = new LowerExpressionStateObject(getParent(), pop());
        add(stateObject);
        return (T) this;
    }

    @Override
    public T lowerThan(Number number) {
        comparison(LOWER_THAN, buildNumeric(number));
        return (T) this;
    }

    @Override
    public T lowerThan(String literal) {
        comparison(LOWER_THAN, literal(literal));
        return (T) this;
    }

    @Override
    public T lowerThan(T builder) {
        checkBuilder(builder);
        comparison(LOWER_THAN);
        return (T) this;
    }

    @Override
    public T lowerThanOrEqual(Number number) {
        comparison(LOWER_THAN_OR_EQUAL, buildNumeric(number));
        return (T) this;
    }

    @Override
    public T lowerThanOrEqual(String literal) {
        comparison(LOWER_THAN_OR_EQUAL, literal(literal));
        return (T) this;
    }

    @Override
    public T lowerThanOrEqual(T builder) {
        checkBuilder(builder);
        comparison(LOWER_THAN_OR_EQUAL);
        return (T) this;
    }

    protected void member(boolean not, boolean of, String collectionValuedPathExpression) {

        StateObject entity = pop();

        StateObject stateObject = new CollectionMemberExpressionStateObject(
            getParent(),
            entity,
            not,
            of,
            collectionValuedPathExpression
        );

        add(stateObject);
    }

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

    @Override
    public T memberOf(String path) {
        member(false, true, path);
        return (T) this;
    }

    @Override
    public T notBetween(T lowerBoundExpression, T upperBoundExpression) {
        checkBuilders(lowerBoundExpression, upperBoundExpression);
        between(true);
        return (T) this;
    }

    @Override
    public T notExists(SimpleSelectStatementStateObject subquery) {
        exists(true, subquery);
        return (T) this;
    }

    @Override
    public T notIn(SimpleSelectStatementStateObject subquery) {
        in(true, Collections.<StateObject>singletonList(subquery));
        return (T) this;
    }

    @Override
    public T notIn(String... inItems) {
        in(true, inItems);
        return (T) this;
    }

    @Override
    public T notIn(T... inItems) {
        checkBuilders(inItems);
        in(true, inItems);
        return (T) this;
    }

    @Override
    public T notLike(String patternValue) {
        notLike(string(patternValue));
        return (T) this;
    }

    @Override
    public T notLike(T builder) {
        checkBuilder(builder);
        like(true, null);
        return (T) this;
    }

    @Override
    public T notLike(T builder, String escapeCharacter) {
        checkBuilder(builder);
        like(true, escapeCharacter);
        return (T) this;
    }

    @Override
    public T notMember(String path) {
        member(true, false, path);
        return (T) this;
    }

    @Override
    public T notMemberOf(String path) {
        member(true, true, path);
        return (T) this;
    }

    @Override
    public T NULL() {
        keyword(NULL);
        return (T) this;
    }

    @Override
    public T or(T builder) {

        checkBuilder(builder);

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

        StateObject stateObject = new OrExpressionStateObject(
            getParent(),
            leftStateObject,
            rightStateObject
        );

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

    @Override
    public T some(SimpleSelectStatementStateObject subquery) {
        allOrAny(SOME, subquery);
        return (T) this;
    }

    @Override
    public T sub(StateObject stateObject) {
        stateObject = new SubExpressionStateObject(getParent(), stateObject);
        add(stateObject);
        return (T) this;
    }

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

        checkBuilders(parameter1, parameter2, parameter3);

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

        StateObject stateObject = new SubstringExpressionStateObject(
            getParent(),
            firstStateObject,
            secondStateObject,
            thirdStateObject
        );

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

    @Override
    public T trim(Specification specification, String trimCharacter, T builder) {

        checkBuilder(builder);
        StateObject stateObject = pop();

        stateObject = new TrimExpressionStateObject(
            getParent(),
            specification,
            ExpressionTools.stringIsNotEmpty(trimCharacter) ? literal(trimCharacter) : null,
            stateObject
        );

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

    @Override
    public T trim(Specification specification, T builder) {
        return trim(specification, null, builder);
    }

    @Override
    public T TRUE() {
        keyword(TRUE);
        return (T) this;
    }

    @Override
    public T upper(T builder) {
        checkBuilder(builder);
        StateObject stateObject = new UpperExpressionStateObject(getParent(), pop());
        add(stateObject);
        return (T) this;
    }

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