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

/**
 * The <code>new_value</code> specified for an update operation must be compatible in type with the
 * field to which it is assigned.
 *
 * <div><b>BNF:</b> <code>update_item ::= [identification_variable.]{state_field | single_valued_association_field} = new_value</code><p></p></div>
 *
 * @see UpdateClause
 *
 * @version 2.5
 * @since 2.3
 * @author Pascal Filion
 */
public final class UpdateItem extends AbstractExpression {

    /**
     * Determines whether the equal sign was parsed or not.
     */
    private boolean hasEqualSign;

    /**
     * Determines whether a whitespace was parsed after the equal sign or not.
     */
    private boolean hasSpaceAfterEqualSign;

    /**
     * Determines whether a whitespace was parsed before the equal sign or not
     */
    private boolean hasSpaceAfterStateFieldPathExpression;

    /**
     * The expression representing the new value.
     */
    private AbstractExpression newValue;

    /**
     * The expression representing the state field to have its value updated.
     */
    private AbstractExpression stateFieldExpression;

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

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

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

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

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

        // State field expression
        if (stateFieldExpression != null) {
            children.add(stateFieldExpression);
        }

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

        // '='
        if (hasEqualSign) {
            children.add(buildStringExpression(EQUAL));
        }

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

        // New value
        if (newValue != null) {
            children.add(newValue);
        }
    }

    @Override
    public JPQLQueryBNF findQueryBNF(Expression expression) {

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

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

        return super.findQueryBNF(expression);
    }

    /**
     * Returns the {@link Expression} representing the new value, which is the new value of the property.
     *
     * @return The expression for the new value
     */
    public Expression getNewValue() {
        if (newValue == null) {
            newValue = buildNullExpression();
        }
        return newValue;
    }

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

    /**
     * Returns the {@link Expression} representing the state field path expression, which is the
     * property that should get updated.
     *
     * @return The expression for the state field path expression
     */
    public Expression getStateFieldPathExpression() {
        if (stateFieldExpression == null) {
            stateFieldExpression = buildNullExpression();
        }
        return stateFieldExpression;
    }

    /**
     * Determines whether the equal sign was parsed or not.
     *
     * @return <code>true</code> if the equal sign was parsed; <code>false</code> otherwise
     */
    public boolean hasEqualSign() {
        return hasEqualSign;
    }

    /**
     * Determines whether the new value section of the query was parsed.
     *
     * @return <code>true</code> the new value was parsed; <code>false</code> if nothing was parsed
     */
    public boolean hasNewValue() {
        return newValue != null &&
              !newValue.isNull();
    }

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

    /**
     * Determines whether a whitespace was parsed after the state field path expression not.
     *
     * @return <code>true</code> if there was a whitespace after the state field path expression;
     * <code>false</code> otherwise
     */
    public boolean hasSpaceAfterStateFieldPathExpression() {
        return hasSpaceAfterStateFieldPathExpression;
    }

    /**
     * Determines whether the state field was parsed.
     *
     * @return <code>true</code> the state field was parsed; <code>false</code> otherwise
     */
    public boolean hasStateFieldPathExpression() {
        return stateFieldExpression != null &&
              !stateFieldExpression.isNull();
    }

    @Override
    protected boolean isParsingComplete(WordParser wordParser, String word, Expression expression) {
        return word.equals(EQUAL) ||
               super.isParsingComplete(wordParser, word, expression);
    }

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

        // Parse state field
        if (tolerant) {
            stateFieldExpression = parse(wordParser, UpdateItemStateFieldPathExpressionBNF.ID, tolerant);
        }
        else {
            stateFieldExpression = new StateFieldPathExpression(this, wordParser.word());
            stateFieldExpression.parse(wordParser, tolerant);
        }

        hasSpaceAfterStateFieldPathExpression = wordParser.skipLeadingWhitespace() > 0;

        // Parse '='
        hasEqualSign = wordParser.startsWith(EQUAL);

        if (hasEqualSign) {
            wordParser.moveForward(1);
            hasSpaceAfterEqualSign = wordParser.skipLeadingWhitespace() > 0;
            if (stateFieldExpression != null) {
                hasSpaceAfterStateFieldPathExpression = true;
            }
        }

        // Parse new value
        newValue = parse(wordParser, NewValueBNF.ID, tolerant);

        if (!hasSpaceAfterEqualSign && (newValue != null)) {
            hasSpaceAfterEqualSign = true;
        }
    }

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

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

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

        // '='
        if (hasEqualSign) {
            writer.append(EQUAL);
        }

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

        // New value
        if (newValue != null) {
            newValue.toParsedText(writer, actual);
        }
    }
}
