/*
 * 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.WordParser;

/**
 * A <code><b>SELECT</b></code> query is an operation that retrieves data from one or more tables or
 * views.
 * <br>
 * JPA:
 * <div><b>BNF:</b> <code>select_statement ::= select_clause
 *                                                    from_clause
 *                                                    [where_clause]
 *                                                    [groupby_clause]
 *                                                    [having_clause]
 *                                                    [orderby_clause]</code></div>
 * <br>
 * EclipseLink 2.4:
 * <div><b>BNF:</b> <code>select_statement ::= select_clause
 *                                                    from_clause
 *                                                    [where_clause]
 *                                                    [groupby_clause]
 *                                                    [having_clause]
 *                                                    [orderby_clause]
 *                                                    {union_clause}*</code></div>
 * <br>
 * HQL query (EclipseLink 2.5):
 * <div><b>BNF:</b> <code>select_statement ::= [select_clause]
 *                                                    from_clause
 *                                                    [where_clause]
 *                                                    [groupby_clause]
 *                                                    [having_clause]
 *                                                    [orderby_clause]
 *                                                    {union_clause}*</code></div>
 *
 * @see FromClause
 * @see GroupByClause
 * @see HavingClause
 * @see HierarchicalQueryClause
 * @see OrderByClause
 * @see SelectClause
 * @see UnionClause
 * @see WhereClause
 *
 * @version 2.5
 * @since 2.3
 * @author Pascal Filion
 */
public final class SelectStatement extends AbstractSelectStatement {

    /**
     * Determines whether there is a whitespace after the select statement parsed by the superclass
     * and the <b>ORDER BY</b> identifier.
     */
    private boolean hasSpaceBeforeOrderBy;

    /**
     * Determines whether there is a whitespace after the select statement parsed by the superclass
     * and the <b>UNION</b> identifier.
     */
    private boolean hasSpaceBeforeUnion;

    /**
     * The <b>ORDER BY</b> expression.
     */
    private AbstractExpression orderByClause;

    /**
     * The <b>UNION</b> expression.
     */
    private AbstractExpression unionClauses;

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

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

    @Override
    public void acceptChildren(ExpressionVisitor visitor) {
        super.acceptChildren(visitor);
        getOrderByClause().accept(visitor);
        getUnionClauses().accept(visitor);
    }

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

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

        super.addOrderedChildrenTo(children);

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

        // 'ORDER BY' clause
        if (orderByClause != null) {
            children.add(orderByClause);
        }

        // 'UNION' clauses
        if (unionClauses != null) {
            children.add(unionClauses);
        }
    }

    @Override
    protected FromClause buildFromClause() {
        return new FromClause(this);
    }

    @Override
    protected SelectClause buildSelectClause() {
        return new SelectClause(this);
    }

    @Override
    public JPQLQueryBNF findQueryBNF(Expression expression) {

        if ((orderByClause != null) && orderByClause.isAncestor(expression)) {
            return orderByClause.getQueryBNF();
        }

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

        return super.findQueryBNF(expression);
    }

    /**
     * Returns the {@link Expression} representing the <b>ORDER BY</b> clause.
     *
     * @return The expression representing the <b>ORDER BY</b> clause
     */
    public Expression getOrderByClause() {
        if (orderByClause == null) {
            orderByClause = buildNullExpression();
        }
        return orderByClause;
    }

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

    /**
     * Returns the {@link Expression} representing the <b>UNION</b> clauses.
     *
     * @return The {@link Expression} representing the <b>UNION</b> clauses
     */
    public Expression getUnionClauses() {
        if (unionClauses == null) {
            unionClauses = buildNullExpression();
        }
        return unionClauses;
    }

    /**
     * Determines whether the <b>ORDER BY</b> clause is defined or not.
     *
     * @return <code>true</code> if the query that got parsed had the <b>ORDER BY</b> clause
     */
    public boolean hasOrderByClause() {
        return orderByClause != null &&
              !orderByClause.isNull();
    }

    /**
     * Determines whether a whitespace was parsed before the <b>ORDER BY</b> clause. In some cases,
     * the space could be owned by a child of the previous clause.
     *
     * @return <code>true</code> if there was a whitespace before the <b>ORDER BY</b>; <code>false</code>
     * otherwise
     */
    public boolean hasSpaceBeforeOrderBy() {
        return hasSpaceBeforeOrderBy;
    }

    /**
     * Determines whether a whitespace was parsed before the <b>UNION</b> clause. In some cases,
     * the space could be owned by a child of the previous clause.
     *
     * @return <code>true</code> if there was a whitespace before the <b>UNION</b>;
     * <code>false</code> otherwise
     */
    public boolean hasSpaceBeforeUnion() {
        return hasSpaceBeforeUnion;
    }

    /**
     * Determines whether at least one <b>UNION</b> clause was defined.
     *
     * @return <code>true</code> if the query that got parsed had the <b>UNION</b> clauses
     */
    public boolean hasUnionClauses() {
        return unionClauses != null &&
              !unionClauses.isNull();
    }

    @Override
    protected boolean isParsingComplete(WordParser wordParser, String word, Expression expression) {

        if (word.equalsIgnoreCase(UNION)     ||
            word.equalsIgnoreCase(INTERSECT) ||
            word.equalsIgnoreCase(EXCEPT)) {

            return false;
        }

        return super.isParsingComplete(wordParser, word, expression);
    }

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

        super.parse(wordParser, tolerant);

        hasSpaceBeforeOrderBy = wordParser.skipLeadingWhitespace() > 0;

        // Parse 'ORDER BY'
        if (wordParser.startsWithIdentifier(ORDER_BY)) {
            orderByClause = new OrderByClause(this);
            orderByClause.parse(wordParser, tolerant);
        }

        // Parse the union clauses and make sure the grammar supports it
        if (getQueryBNF(UnionClauseBNF.ID) != null) {
            hasSpaceBeforeUnion = wordParser.skipLeadingWhitespace() > 0;
            unionClauses = parse(wordParser, UnionClauseBNF.ID, tolerant);
        }
    }

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

        super.toParsedText(writer, actual);

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

        // 'ORDER BY' clause
        if (hasOrderByClause()) {
            orderByClause.toParsedText(writer, actual);
        }

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

        // 'UNION' clauses
        if (hasUnionClauses()) {
            unionClauses.toParsedText(writer, actual);
        }
    }
}
