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

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

/**
 * A query is an operation that retrieves data from one or more tables or views. In this reference,
 * a top-level <code><b>SELECT</b></code> statement is called a query, and a query nested within
 * another SQL statement is called a subquery.
 *
 * @see SelectStatement
 * @see SimpleSelectStatement
 *
 * @version 2.5
 * @since 2.3
 * @author Pascal Filion
 */
public abstract class AbstractSelectStatement extends AbstractExpression {

    /**
     * The <code><b>FROM</b></code> clause of this select statement.
     */
    private AbstractExpression fromClause;

    /**
     * The <code><b>GROUP BY</b></code> clause of this select statement.
     */
    private AbstractExpression groupByClause;

    /**
     * Determines whether there is a whitespace after the identifier <code><b>FROM</b></code>.
     */
    private boolean hasSpaceAfterFrom;

    /**
     * Determines whether there is a whitespace after the identifier <code><b>GROUP BY</b></code>.
     */
    private boolean hasSpaceAfterGroupBy;

    /**
     * Determines whether there is a whitespace after the identifier <code><b>SELECT</b></code>.
     */
    private boolean hasSpaceAfterSelect;

    /**
     * Determines whether there is a whitespace after the identifier <code><b>WHERE</b></code>.
     */
    private boolean hasSpaceAfterWhere;

    /**
     * The <code><b>HAVING</b></code> clause of this select statement.
     */
    private AbstractExpression havingClause;

    /**
     * The <code><b>SELECT</b></code> clause of this select statement.
     */
    private AbstractExpression selectClause;

    /**
     * The <code><b>WHERE</b></code> clause of this select statement.
     */
    private AbstractExpression whereClause;

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

    /**
     * {@inheritDoc}
     */
    @Override
    public void acceptChildren(ExpressionVisitor visitor) {
        getSelectClause().accept(visitor);
        getFromClause().accept(visitor);
        getWhereClause().accept(visitor);
        getGroupByClause().accept(visitor);
        getHavingClause().accept(visitor);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void addChildrenTo(Collection<Expression> children) {
        children.add(getSelectClause());
        children.add(getFromClause());
        children.add(getWhereClause());
        children.add(getGroupByClause());
        children.add(getHavingClause());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void addOrderedChildrenTo(List<Expression> children) {

        // SELECT clause
        if (selectClause != null) {
            children.add(selectClause);
        }

        // Space between SELECT and FROM clauses
        if (hasSpaceAfterSelect) {
            children.add(buildStringExpression(SPACE));
        }

        // FROM clause
        if (fromClause != null) {
            children.add(fromClause);
        }

        // Space between the FROM clause and an optional clause
        if (hasSpaceAfterFrom) {
            children.add(buildStringExpression(SPACE));
        }

        // WHERE clause
        if (whereClause != null) {
            children.add(whereClause);
        }

        // Space between WHERE clause and another optional clause
        if (hasSpaceAfterWhere) {
            children.add(buildStringExpression(SPACE));
        }

        // GROUP BY clause
        if (groupByClause != null) {
            children.add(groupByClause);
        }

        // Space between GROUP BY clause and another optional clause
        if (hasSpaceAfterGroupBy) {
            children.add(buildStringExpression(SPACE));
        }

        // HAVING clause
        if (havingClause != null) {
            children.add(havingClause);
        }
    }

    /**
     * Creates the expression representing the from clause of this select statement.
     *
     * @return A new from clause, <code>null</code> can't be returned
     */
    protected abstract AbstractFromClause buildFromClause();

    /**
     * Creates the expression representing the select clause of this select statement.
     *
     * @return A new from clause, <code>null</code> can't be returned
     */
    protected abstract AbstractSelectClause buildSelectClause();

    /**
     * {@inheritDoc}
     */
    @Override
    public JPQLQueryBNF findQueryBNF(Expression expression) {

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

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

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

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

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

        return super.findQueryBNF(expression);
    }

    /**
     * Returns the {@link Expression} representing the <b>FROM</b> clause.
     *
     * @return The expression representing the <b>FROM</b> clause
     */
    public final Expression getFromClause() {
        if (fromClause == null) {
            fromClause = buildNullExpression();
        }
        return fromClause;
    }

    /**
     * Returns the {@link Expression} representing the <b>GROUP BY</b> clause.
     *
     * @return The expression representing the <b>GROUP BY</b> clause
     */
    public final Expression getGroupByClause() {
        if (groupByClause == null) {
            groupByClause = buildNullExpression();
        }
        return groupByClause;
    }

    /**
     * Returns the {@link Expression} representing the <b>HAVING</b> clause.
     *
     * @return The expression representing the <b>HAVING</b> clause
     */
    public final Expression getHavingClause() {
        if (havingClause == null) {
            havingClause = buildNullExpression();
        }
        return havingClause;
    }

    /**
     * Returns the {@link AbstractSelectClause} representing the <b>SELECT</b> clause.
     *
     * @return The expression representing the <b>SELECT</b> clause
     */
    public final Expression getSelectClause() {
        if (selectClause == null) {
            selectClause = buildNullExpression();
        }
        return selectClause;
    }

    /**
     * Returns the {@link Expression} representing the <b>WHERE</b> clause.
     *
     * @return The expression representing the <b>WHERE</b> clause
     */
    public final Expression getWhereClause() {
        if (whereClause == null) {
            whereClause = buildNullExpression();
        }
        return whereClause;
    }

    /**
     * Determines whether the <b>FROM</b> clause was parsed or not.
     *
     * @return <code>true</code> if the query that got parsed had the <b>FROM</b> clause
     */
    public final boolean hasFromClause() {
        return fromClause != null &&
              !fromClause.isNull();
    }

    /**
     * Determines whether the <b>GROUP BY</b> clause was parsed or not.
     *
     * @return <code>true</code> if the query that got parsed had the <b>GROUP BY</b> clause
     */
    public final boolean hasGroupByClause() {
        return groupByClause != null &&
              !groupByClause.isNull();
    }

    /**
     * Determines whether the <b>HAVING</b> clause was parsed or not.
     *
     * @return <code>true</code> if the query that got parsed had the <b>HAVING</b> clause
     */
    public final boolean hasHavingClause() {
        return havingClause != null &&
              !havingClause.isNull();
    }

    /**
     * Determines whether the <b>SELECT</b> clause was parsed or not.
     *
     * @return <code>true</code> if the query that got parsed had the <b>HAVING</b> clause
     * @since 2.5
     */
    public final boolean hasSelectClause() {
        return selectClause != null &&
              !selectClause.isNull();
    }

    /**
     * Determines whether a whitespace was found after the <b>FROM</b> clause. In some cases, the
     * space is owned by a child of the <b>FROM</b> clause.
     *
     * @return <code>true</code> if there was a whitespace after the <b>FROM</b> clause and owned by
     * this expression; <code>false</code> otherwise
     */
    public final boolean hasSpaceAfterFrom() {
        return hasSpaceAfterFrom;
    }

    /**
     * Determines whether a whitespace was found after the <b>GROUP BY</b> clause. In some cases, the
     * space is owned by a child of the <b>GROUP BY</b> clause.
     *
     * @return <code>true</code> if there was a whitespace after the <b>GROUP BY</b> clause and owned
     * by this expression; <code>false</code> otherwise
     */
    public final boolean hasSpaceAfterGroupBy() {
        return hasSpaceAfterGroupBy;
    }

    /**
     * Determines whether a whitespace was found after the <b>SELECT</b> clause. In some cases, the
     * space is owned by a child of the <b>SELECT</b> clause.
     *
     * @return <code>true</code> if there was a whitespace after the <b>SELECT</b> clause and owned
     * by this expression; <code>false</code> otherwise
     */
    public final boolean hasSpaceAfterSelect() {
        return hasSpaceAfterSelect;
    }

    /**
     * Determines whether a whitespace was found after the <b>WHERE</b> clause. In some cases, the
     * space is owned by a child of the <b>WHERE</b> clause.
     *
     * @return <code>true</code> if there was a whitespace after the <b>WHERE</b> clause and owned by
     * this expression; <code>false</code> otherwise
     */
    public final boolean hasSpaceAfterWhere() {
        return hasSpaceAfterWhere;
    }

    /**
     * Determines whether the <b>WHERE</b> clause is defined.
     *
     * @return <code>true</code> if the query that got parsed had the <b>WHERE</b> clause
     */
    public final boolean hasWhereClause() {
        return whereClause != null &&
              !whereClause.isNull();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void parse(WordParser wordParser, boolean tolerant) {

        // Parse 'SELECT' clause
        if (wordParser.startsWithIdentifier(SELECT)) {
            selectClause = buildSelectClause();
            selectClause.parse(wordParser, tolerant);

            hasSpaceAfterSelect = wordParser.skipLeadingWhitespace() > 0;
        }

        // Parse 'FROM' clause
        if (wordParser.startsWithIdentifier(FROM)) {
            fromClause = buildFromClause();
            fromClause.parse(wordParser, tolerant);

            hasSpaceAfterFrom = wordParser.skipLeadingWhitespace() > 0;
        }

        // Parse 'WHERE' clause
        if (wordParser.startsWithIdentifier(WHERE)) {
            whereClause = new WhereClause(this);
            whereClause.parse(wordParser, tolerant);

            hasSpaceAfterWhere = wordParser.skipLeadingWhitespace() > 0;
        }

        // Parse 'GROUP BY' clause
        if (wordParser.startsWithIdentifier(GROUP_BY)) {
            groupByClause = new GroupByClause(this);
            groupByClause.parse(wordParser, tolerant);

            hasSpaceAfterGroupBy = wordParser.skipLeadingWhitespace() > 0;
        }

        // Parse 'HAVING' clause
        if (wordParser.startsWithIdentifier(HAVING)) {
            havingClause = new HavingClause(this);
            havingClause.parse(wordParser, tolerant);
        }

        if (!wordParser.isTail() && !shouldManageSpaceAfterClause()) {

            if (hasSpaceAfterFrom     &&
                whereClause == null   &&
                groupByClause == null &&
                havingClause == null) {

                hasSpaceAfterFrom = false;
                wordParser.moveBackward(1);
            }
            else if (hasSpaceAfterWhere    &&
                     groupByClause == null &&
                     havingClause  == null) {

                hasSpaceAfterWhere = false;
                wordParser.moveBackward(1);
            }
            else if (hasSpaceAfterGroupBy &&
                     havingClause  == null) {

                hasSpaceAfterGroupBy = false;
                wordParser.moveBackward(1);
            }
        }
    }

    /**
     * Determines whether the whitespace following the <code><b>HAVING</b></code> clause should be
     * managed by this expression or not.
     *
     * @return <code>true</code> by default to keep the whitespace part of this expression;
     * <code>false</code> to let the parent handle it
     */
    protected boolean shouldManageSpaceAfterClause() {
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void toParsedText(StringBuilder writer, boolean actual) {

        // SELECT clause
        if (selectClause != null) {
            selectClause.toParsedText(writer, actual);
        }

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

        // FROM clause
        if (fromClause != null) {
            fromClause.toParsedText(writer, actual);
        }

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

        // WHERE clause
        if (whereClause != null) {
            whereClause.toParsedText(writer, actual);
        }

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

        // GROUP BY clause
        if (groupByClause != null) {
            groupByClause.toParsedText(writer, actual);
        }

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

        // HAVING clause
        if (havingClause != null) {
            havingClause.toParsedText(writer, actual);
        }
    }
}
