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

import java.util.Collection;
import java.util.List;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.WordParser;

/**
 * An orderby_item must be one of the following:
 * <ol>
 * <li> A {@link StateFieldPathExpression state_field_path_expression} that evaluates to an orderable
 * state field of an entity or embeddable class abstract schema type designated in the SELECT clause
 * by one of the following:
 *   <ul>
 *   <li>A general_identification_variable
 *   <li>A single_valued_object_path_expression
 *   </ul>
 * <li>A {@link StateFieldPathExpression state_field_path_expression} that evaluates to the same
 * state field of the same entity or embeddable abstract schema type as a {@link StateFieldPathExpression
 * state_field_path_expression} in the <b>SELECT</b> clause
 * <li>A {@link ResultVariable result_variable} that refers to an orderable item in the <b>SELECT</b>
 * clause for which the same {@link ResultVariable result_variable} has been specified. This may be
 * the result of an aggregate_expression, a <code>scalar_expression</code>, or a {@link
 * StateFieldPathExpression state_field_path_expression} in the <b>SELECT</b> clause.
 * </ol>
 * <p></p>
 * The keyword <b>ASC</b> specifies that ascending ordering be used for the associated orderby_item;
 * the keyword <b>DESC</b> specifies that descending ordering be used. Ascending ordering is the
 * default.
 * <p></p>
 * The keyword <b>NULLS FIRST</b> specifies that nulls first ordering be used for the associated orderby_item;
 * the keyword <b>NULLS LAST</b> specifies that nulls last ordering be used. Ascending ordering is the
 * default.
 * <p></p>
 * JPA 1.0:
 * <div><b>BNF:</b> <code>orderby_item ::= state_field_path_expression [ ASC | DESC ]</code></div>
 * <p></p>
 * JPA 2.0
 * <div><b>BNF:</b> <code>orderby_item ::= state_field_path_expression | result_variable [ ASC | DESC ]</code></div>
 * <p></p>
 * EclipseLink 2.4:
 * <div><b>BNF:</b> <code>orderby_item ::= state_field_path_expression | result_variable [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ]</code></div>
 * <p></p>
 *
 * @version 2.5
 * @since 2.3
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public final class OrderByItem extends AbstractExpression {

    /**
     * The {@link Expression} representing the order by expression.
     */
    private AbstractExpression expression;

    /**
     * The actual 'FIRST' identifier found in the string representation of the JPQL query.
     */
    private String firstIdentifier;

    /**
     * Determines whether a whitespace was parsed after the order by expression.
     */
    private boolean hasSpaceAfterExpression;

    /**
     * Determines whether a whitespace was parsed after <code><b>NULLS</b></code>.
     */
    private boolean hasSpaceAfterNulls;

    /**
     * Determines whether a whitespace was parsed after the ordering.
     */
    private boolean hasSpaceAfterOrdering;

    /**
     * The actual 'LAST' identifier found in the string representation of the JPQL query.
     */
    private String lastIdentifier;

    /**
     * The keyword <b>NULLS FIRST</b> specifies ordering null first; the keyword <b>NULLS LAST</b>
     * specifies ordering nulls last.
     */
    private NullOrdering nullOrdering;

    /**
     * The actual 'NULLS' identifier found in the string representation of the JPQL query.
     */
    private String nullsIdentifier;

    /**
     * The keyword <b>ASC</b> specifies that ascending ordering be used; the keyword <b>DESC</b>
     * specifies that descending ordering be used. Ascending ordering is the default.
     */
    private Ordering ordering;

    /**
     * The actual ordering identifier found in the string representation of the JPQL query.
     */
    private String orderingIdentifier;

    /**
     * Creates a new <code>OrderByItem</code>.
     *
     * @param parent The parent of this expression
     */
    public OrderByItem(AbstractExpression parent) {
        super(parent);
    }

    @Override
    public void accept(ExpressionVisitor visitor) {
        visitor.visit(this);
    }

    @Override
    public void acceptChildren(ExpressionVisitor visitor) {
        getExpression().accept(visitor);
    }

    @Override
    protected void addChildrenTo(Collection<Expression> children) {
        children.add(getExpression());
    }

    @Override
    protected void addOrderedChildrenTo(List<Expression> children) {

        // Order By expression
        if (expression != null) {
            children.add(expression);
        }

        if (hasSpaceAfterExpression) {
            children.add(buildStringExpression(SPACE));
        }

        // Ordering type
        if (ordering != Ordering.DEFAULT) {
            children.add(buildStringExpression(ordering.toString()));
        }

        if (hasSpaceAfterOrdering) {
            children.add(buildStringExpression(SPACE));
        }

        // 'NULLS'
        if (nullsIdentifier != null) {
            children.add(buildStringExpression(NULLS));
        }

        if (hasSpaceAfterNulls) {
            children.add(buildStringExpression(SPACE));
        }

        // 'FIRST'
        if (firstIdentifier != null) {
            children.add(buildStringExpression(FIRST));
        }
        // 'LAST'
        else if (lastIdentifier != null) {
            children.add(buildStringExpression(LAST));
        }
    }

    @Override
    public JPQLQueryBNF findQueryBNF(Expression expression) {

        if ((this.expression != null) && this.expression.isAncestor(expression)) {
            return getQueryBNF(InternalOrderByItemBNF.ID);
        }

        return super.findQueryBNF(expression);
    }

    /**
     * Returns the actual <code>null</code> ordering identifier found in the string representation of
     * the JPQL query, which has the actual case that was used.
     *
     * @return The <code>null</code> ordering identifier that was actually parsed, if one was present,
     * otherwise an empty string is returned
     */
    public String getActualNullOrdering() {

        // NULLS FIRST
        if ((nullsIdentifier != null) && (firstIdentifier != null)) {
            return nullsIdentifier + SPACE + firstIdentifier;
        }

        // NULLS LAST
        if ((nullsIdentifier != null) && (lastIdentifier != null)) {
            return nullsIdentifier + SPACE + lastIdentifier;
        }

        if (nullsIdentifier != null) {
            return nullsIdentifier;
        }

        if (firstIdentifier != null) {
            return firstIdentifier;
        }
        else if (lastIdentifier != null) {
            return lastIdentifier;
        }

        return ExpressionTools.EMPTY_STRING;
    }

    /**
     * Returns the actual ordering identifier found in the string representation of the JPQL query,
     * which has the actual case that was used.
     *
     * @return The ordering identifier that was actually parsed, if one was present, otherwise an
     * empty string is returned
     */
    public String getActualOrdering() {
        return (orderingIdentifier != null) ? orderingIdentifier : ExpressionTools.EMPTY_STRING;
    }

    /**
     * Returns the {@link Expression} that represents the order by expression.
     *
     * @return The expression that was parsed representing the order by expression
     */
    public Expression getExpression() {
        if (expression == null) {
            expression = buildNullExpression();
        }
        return expression;
    }

    /**
     * Returns the enum constant representing the null ordering type.
     *
     * @return The constant representing the null ordering, in the case the ordering was not parsed,
     * then {@link NullOrdering#DEFAULT} is returned
     */
    public NullOrdering getNullOrdering() {
        return nullOrdering;
    }

    /**
     * Returns the enum constant representing the ordering type.
     *
     * @return The constant representing the ordering, in the case the ordering was not parsed, then
     * {@link Ordering#DEFAULT} is returned
     */
    public Ordering getOrdering() {
        return ordering;
    }

    @Override
    public JPQLQueryBNF getQueryBNF() {
        return getQueryBNF(OrderByItemBNF.ID);
    }

    /**
     * Determines whether the order by expression was parsed.
     *
     * @return <code>true</code> if the order by expression was parsed; <code>false</code> otherwise
     */
    public boolean hasExpression() {
        return expression != null &&
              !expression.isNull();
    }

    /**
     * Determines whether the <code><b>NULLS</b></code> identifier was parsed.
     *
     * @return <code>true</code> if the <code><b>NULLS</b></code> identifier was parsed;
     *  <code>false</code> otherwise
     */
    public boolean hasNulls() {
        return nullsIdentifier != null;
    }

    /**
     * Determines whether <code><b>ASC</b></code> or <code><b>DESC</b></code> was parsed.
     *
     * @return <code>true</code> if the ordering status was parsed; <code>false</code> otherwise
     * @since 2.5
     */
    public boolean hasOrdering() {
        return ordering != Ordering.DEFAULT;
    }

    /**
     * Determines whether a whitespace was parsed after the order by expression.
     *
     * @return <code>true</code> if there was a whitespace after the order by expression;
     * <code>false</code> otherwise
     */
    public boolean hasSpaceAfterExpression() {
        return hasSpaceAfterExpression;
    }

    /**
     * Determines whether a whitespace was parsed after the <code>NULLS</code> identifier. If the
     * composite identifier was fully parsed - <code>NULLS FIRST</code> or <code>NULLS LAST</code> -
     * then this is always <code>true</code>, but if only <code>NULLS</code> was parsed, then this
     * can be useful to determine if there was a space after.
     *
     * @return <code>true</code> if there was a whitespace after the <code>NULLS</code> identifier;
     * <code>false</code> otherwise
     */
    public boolean hasSpaceAfterNulls() {
        return hasSpaceAfterNulls;
    }

    /**
     * Determines whether a whitespace was parsed after the ordering.
     *
     * @return <code>true</code> if there was a whitespace after the ordering;
     * <code>false</code> otherwise
     */
    public boolean hasSpaceAfterOrdering() {
        return hasSpaceAfterOrdering;
    }

    /**
     * Determines whether the ordering was specified as being ascendant.
     *
     * @return <code>true</code> if <b>ASC</b> was parsed; <code>false</code> otherwise
     */
    public boolean isAscending() {
        return ordering == Ordering.ASC;
    }

    /**
     * Determines whether the ordering was not specified.
     *
     * @return <code>true</code> if no ordering was parsed; <code>false</code> otherwise
     */
    public boolean isDefault() {
        return ordering == Ordering.DEFAULT;
    }

    /**
     * Determines whether the ordering was specified as being descendant.
     *
     * @return <code>true</code> if <b>DESC</b> was parsed; <code>false</code> otherwise
     */
    public boolean isDescending() {
        return ordering == Ordering.DESC;
    }

    /**
     * Determines whether the ordering was specified as being nulls first.
     *
     * @return <code>true</code> if <b>NULLS FIRST</b> was parsed; <code>false</code> otherwise
     */
    public boolean isNullsFirst() {
        return nullOrdering == NullOrdering.NULLS_FIRST;
    }

    /**
     * Determines whether the ordering was specified as being nulls first.
     *
     * @return <code>true</code> if <b>NULLS LAST</b> was parsed; <code>false</code> otherwise
     */
    public boolean isNullsLast() {
        return nullOrdering == NullOrdering.NULLS_LAST;
    }

    @Override
    protected boolean isParsingComplete(WordParser wordParser, String word, Expression expression) {
        return word.equalsIgnoreCase(ASC)     ||
               word.equalsIgnoreCase(DESC)    ||
               word.equalsIgnoreCase("NULLS") ||
               super.isParsingComplete(wordParser, word, expression);
    }

    @Override
    protected void parse(WordParser wordParser, boolean tolerant) {

        // Parse the state field path expression
        expression = parse(wordParser, InternalOrderByItemBNF.ID, tolerant);

        hasSpaceAfterExpression = wordParser.skipLeadingWhitespace() > 0;

        // Parse ASC/DESC
        if (!wordParser.isTail()) {
            String word = wordParser.word();

            // Parse 'ASC'
            if (word.equalsIgnoreCase(ASC)) {
                ordering = Ordering.ASC;
                orderingIdentifier = wordParser.moveForward(ASC.length());
            }
            // Parse 'DESC'
            else if (word.equalsIgnoreCase(DESC)) {
                ordering = Ordering.DESC;
                orderingIdentifier = wordParser.moveForward(DESC.length());
            }
            else {
                ordering = Ordering.DEFAULT;
            }
        }
        else {
            ordering = Ordering.DEFAULT;
        }

        // Parse NULLS FIRST/NULLS LAST
        if (!wordParser.isTail()) {
            int count = wordParser.skipLeadingWhitespace();
            hasSpaceAfterOrdering = (count > 0);

            // Parse 'NULLS'
            if (wordParser.startsWithIdentifier(NULLS)) {
                nullsIdentifier = wordParser.moveForward(NULLS);
                hasSpaceAfterNulls = wordParser.skipLeadingWhitespace() > 0;
            }

            // Parse 'FIRT'
            if (wordParser.startsWithIdentifier(FIRST)) {
                firstIdentifier = wordParser.moveForward(FIRST);
            }
            // Parse 'LAST'
            else if (wordParser.startsWithIdentifier(LAST)) {
                lastIdentifier = wordParser.moveForward(LAST);
            }

            if ((nullsIdentifier != null) && (firstIdentifier != null)) {
                nullOrdering = NullOrdering.NULLS_FIRST;
            }
            else if ((nullsIdentifier != null) && (lastIdentifier != null)) {
                nullOrdering = NullOrdering.NULLS_LAST;
            }
            else {
                nullOrdering = NullOrdering.DEFAULT;
            }
        }
        else {
            nullOrdering = NullOrdering.DEFAULT;
        }
    }

    @Override
    protected void toParsedText(StringBuilder writer, boolean actual) {

        // Order By expression
        if (expression != null) {
            expression.toParsedText(writer, actual);
        }

        if (hasSpaceAfterExpression) {
            writer.append(SPACE);
        }

        // Ordering type
        if (ordering != Ordering.DEFAULT) {
            writer.append(actual ? orderingIdentifier : ordering.name());
        }

        if (hasSpaceAfterOrdering) {
            writer.append(SPACE);
        }

        // 'NULLS'
        if (nullsIdentifier != null) {
            writer.append(actual? nullsIdentifier : NULLS);
        }

        if (hasSpaceAfterNulls) {
            writer.append(SPACE);
        }

        // 'FIRST'
        if (firstIdentifier != null) {
            writer.append(actual? firstIdentifier : FIRST);
        }
        // 'LAST'
        else if (lastIdentifier != null) {
            writer.append(actual? lastIdentifier : LAST);
        }
    }

    /**
     * This enumeration lists all the possible choices for ordering nulls in an item.
     */
    public enum NullOrdering {

        /**
         * The constant used when the ordering is not specify.
         */
        DEFAULT(ExpressionTools.EMPTY_STRING),

        /**
         * The constant for 'NULLS FIRST', which tells to order nulls first.
         */
        NULLS_FIRST(Expression.NULLS_FIRST),

        /**
         * The constant for 'NULLS LAST', which tells to order nulls last.
         */
        NULLS_LAST(Expression.NULLS_LAST);

        /**
         * The actual composite identifier.
         */
        private String identifier;

        /**
         * Creates a new <code>NullOrdering</code>.
         *
         * @param identifier The actual composite identifier
         */
        private NullOrdering(String identifier) {
            this.identifier = identifier;
        }

        /**
         * Returns the actual JPQL composite identifiers identified by this enum constant.
         *
         * @return The composite identifiers
         */
        public String getIdentifier() {
            return identifier;
        }

        @Override
        public String toString() {
            return identifier;
        }
    }

    /**
     * This enumeration lists all the possible choices for ordering an item.
     */
    public enum Ordering {

        /**
         * The constant for 'ASC', which tells to order the items in ascending ordering.
         */
        ASC,

        /**
         * The constant used when the ordering is not specify, the default is ascending ordering.
         */
        DEFAULT,

        /**
         * The constant for 'DESC', which tells to order the items in descending ordering.
         */
        DESC
    }
}
