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

/**
 * <p>An <code><b>AS OF</b></code> clause is part of a flashback query, which provides ways to view
 * past states of database objects, or to return database objects to a previous state, without using
 * traditional point-in-time recovery.
 * </p><p>
 * Specify <code><b>AS OF</b></code> to retrieve the single version of the rows returned by the
 * query at a particular change number (SCN) or timestamp. If you specify SCN, then the expression
 * must evaluate to a number. If you specify <code><b>TIMESTAMP</b></code>, then the expression must
 * evaluate to a timestamp value. Oracle Database returns rows as they existed at the specified
 * system change number or time.
 * </p>
 * <div><b>BNF:</b> <code>asof_clause ::= AS OF { SCN | TIMESTAMP } scalar_expression</code></div>
 *
 * @version 2.5
 * @since 2.5
 * @author Pascal Filion
 */
public final class AsOfClause extends AbstractExpression {

    /**
     * The {@link Expression} representing the timestamp or change number.
     */
    private AbstractExpression expression;

    /**
     * Determines whether a whitespace was found after either <code><b>SCN</b></code> or
     * <code><b>TIMESTAMP</b></code>.
     */
    private boolean hasSpaceAfterCategory;

    /**
     * Determines whether a whitespace was found after <code><b>AS OF</b></code>.
     */
    private boolean hasSpaceAfterIdentifier;

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

    /**
     * The actual <code><b>SCN</b></code> identifier found in the string representation of the
     * JPQL query.
     */
    private String scnIdentifier;

    /**
     * The actual <code><b>TIMESTAMP</b></code> identifier found in the string representation of the
     * JPQL query.
     */
    private String timestampIdentifier;

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

    @Override
    public void accept(ExpressionVisitor visitor) {
        acceptUnknownVisitor(visitor);
    }

    @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) {

        // 'AS OF'
        children.add(buildStringExpression(AS_OF));

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

        // 'SCN'
        if (scnIdentifier != null) {
            children.add(buildStringExpression(SCN));
        }
        // 'TIMESTAMP'
        else if (timestampIdentifier != null) {
            children.add(buildStringExpression(TIMESTAMP));
        }

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

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

    @Override
    public JPQLQueryBNF findQueryBNF(Expression expression) {

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

        return super.findQueryBNF(expression);
    }

    /**
     * Returns the actual <b>AS OF</b> identifier found in the string representation of the JPQL
     * query, which has the actual case that was used.
     *
     * @return The <b>AS OF</b> identifier that was actually parsed
     */
    public String getActualIdentifier() {
        return identifier;
    }

    /**
     * Returns the actual <b>SCN</b> identifier found in the string representation of the JPQL query,
     * which has the actual case that was used.
     *
     * @return The <b>SCN</b> identifier that was actually parsed, or an empty string if it was not parsed
     */
    public String getActualScnIdentifier() {
        return (scnIdentifier != null) ? scnIdentifier : ExpressionTools.EMPTY_STRING;
    }

    /**
     * Returns the actual <b>TIMESTAMP</b> identifier found in the string representation of the JPQL
     * query, which has the actual case that was used.
     *
     * @return The <b>TIMESTAMP</b> identifier that was actually parsed, or an empty string if it was
     * not parsed
     */
    public String getActualTimestampIdentifier() {
        return (timestampIdentifier != null) ? timestampIdentifier : ExpressionTools.EMPTY_STRING;
    }

    /**
     * Returns the {@link Expression} representing the timestamp or change number.
     *
     * @return The {@link Expression} that was parsed representing the timestamp or change number
     */
    public Expression getExpression() {
        if (expression == null) {
            expression = buildNullExpression();
        }
        return expression;
    }

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

    /**
     * Determines whether the {@link Expression} representing the timestamp or change number was
     * parsed or not.
     *
     * @return <code>true</code> if the timestamp or change number was parsed; <code>false</code> otherwise
     */
    public boolean hasExpression() {
        return expression != null &&
              !expression.isNull();
    }

    /**
     * Determines whether the identifier <b>SCN</b> was part of the query.
     *
     * @return <code>true</code> if the identifier <b>SCN</b> was parsed; <code>false</code> otherwise
     */
    public boolean hasScn() {
        return scnIdentifier != null;
    }

    /**
     * Determines whether a whitespace was found after either <b>SCN</b> or <code>TIMESTAMP</code>.
     *
     * @return <code>true</code> if there was a whitespace after <b>SCN</b> or <code>TIMESTAMP</code>;
     * <code>false</code> otherwise
     */
    public boolean hasSpaceAfterCategory() {
        return hasSpaceAfterCategory;
    }

    /**
     * Determines whether a whitespace was found after <b>AS OF</b>.
     *
     * @return <code>true</code> if there was a whitespace after <b>AS OF</b>; <code>false</code> otherwise
     */
    public boolean hasSpaceAfterIdentifier() {
        return hasSpaceAfterIdentifier;
    }

    /**
     * Determines whether the identifier <b>TIMESTAMP</b> was part of the query.
     *
     * @return <code>true</code> if the identifier <b>TIMESTAMP</b> was parsed; <code>false</code> otherwise
     */
    public boolean hasTimestamp() {
        return timestampIdentifier != null;
    }

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

        // 'AS OF'
        identifier = wordParser.moveForwardIgnoreWhitespace(AS_OF);
        hasSpaceAfterIdentifier = wordParser.skipLeadingWhitespace() > 0;

        // 'SCN'
        if (wordParser.startsWithIdentifier(SCN)) {
            scnIdentifier = wordParser.moveForward(SCN);
            hasSpaceAfterCategory = wordParser.skipLeadingWhitespace() > 0;
        }
        // 'TIMESTAMP'
        else if (wordParser.startsWithIdentifier(TIMESTAMP)) {
            timestampIdentifier = wordParser.moveForward(TIMESTAMP);
            hasSpaceAfterCategory = wordParser.skipLeadingWhitespace() > 0;
        }

        // Expression
        expression = parse(wordParser, ScalarExpressionBNF.ID, tolerant);
    }

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

        // 'AS OF'
        writer.append(actual ? identifier : AS_OF);

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

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

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

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

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