/*
 * 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.List;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.WordParser;

/**
 * The <b>TRIM</b> function trims the specified character from a string. If the character to be
 * trimmed is not specified, it is assumed to be space (or blank). The optional <code>trim_character</code>
 * is a single-character string literal or a character-valued input parameter (i.e., char or
 * Character). If a trim specification is not provided, <b>BOTH</b> is assumed. The <b>TRIM</b>
 * function returns the trimmed string.
 * <p>
 * JPA 1.0, 2.0:
 * <div><b>BNF:</b> <code>expression ::= TRIM([[trim_specification] [trim_character] FROM] string_primary)</code></div>
 *
 * <div><b>BNF:</b> <code>trim_character ::= string_literal | input_parameter</code></div>
 * <br>
 * JPA 2.1:
 * <div><b>BNF:</b> <code>expression ::= TRIM([[trim_specification] [trim_character] FROM] string_expression)</code></div>
 *
 * <div><b>BNF:</b> <code>trim_character ::= string_literal | input_parameter</code></div>
 *
 * <div>Example: <code><b>UPDATE</b> Student st <b>SET</b> st.sname=TRIM(st.sname)</code></div>
 *
 * @version 2.5
 * @since 2.3
 * @author Pascal Filion
 */
public final class TrimExpression extends AbstractSingleEncapsulatedExpression {

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

    /**
     * Determines whether the identifier <b>FROM</b> was part of the query.
     */
    private boolean hasFrom;

    /**
     * Determines whether a space was parsed after the identifier <b>FROM</b>.
     */
    private boolean hasSpaceAfterFrom;

    /**
     * Determines whether a space was parsed after the trim specification.
     */
    private boolean hasSpaceAfterSpecification;

    /**
     * Determines whether a space was parsed after the trim character.
     */
    private boolean hasSpaceAfterTrimCharacter;

    /**
     * The specification specifies how to trim the string.
     */
    private Specification specification;

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

    /**
     * The character used for trimming the string.
     */
    private AbstractExpression trimCharacter;

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

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

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

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

        // Trim specification
        if (hasSpecification()) {
            children.add(buildStringExpression(specification.name()));
        }

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

        // Trim character
        if (hasTrimCharacter()) {
            children.add(trimCharacter);
        }

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

        // 'FROM'
        if (hasFrom) {
            children.add(buildStringExpression(FROM));
        }

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

        // String primary
        super.addOrderedEncapsulatedExpressionTo(children);
    }

    @Override
    public String getEncapsulatedExpressionQueryBNFId() {
        return StringPrimaryBNF.ID;
    }

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

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

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

    /**
     * Returns the specification which specifies how to trim the string.
     *
     * @return One of the available choices for trimming the string
     */
    public Specification getSpecification() {
        return specification;
    }

    /**
     * Returns the character used for trimming the string.
     *
     * @return The character, if one was parsed, that will be used to trim the string. If the
     * character was not specified, then '\0' is the character
     */
    public Expression getTrimCharacter() {
        if (trimCharacter == null) {
            trimCharacter = buildNullExpression();
        }
        return trimCharacter;
    }

    @Override
    public boolean hasEncapsulatedExpression() {
        return hasSpecification() || hasTrimCharacter() || hasFrom || hasExpression();
    }

    /**
     * Determines whether the identifier <b>FROM</b> was part of the query.
     *
     * @return <code>true</code> if the identifier <b>FROM</b> was parsed; <code>false</code> otherwise
     */
    public boolean hasFrom() {
        return hasFrom;
    }

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

    /**
     * Determines whether a whitespace was found after the way the string is trimmed.
     *
     * @return <code>true</code> if there was a whitespace after the trim specification;
     * <code>false</code> otherwise
     */
    public boolean hasSpaceAfterSpecification() {
        return hasSpaceAfterSpecification;
    }

    /**
     * Determines whether a whitespace was found after the character used to trim the string.
     *
     * @return <code>true</code> if there was a whitespace after the trim character;
     * <code>false</code> otherwise
     */
    public boolean hasSpaceAfterTrimCharacter() {
        return hasSpaceAfterTrimCharacter;
    }

    /**
     * Determines whether the way the trim is trimmed was parsed.
     *
     * @return <code>true</code> if the query contained the way the trim needs to
     * be trimmed; <code>false</code> otherwise
     */
    public boolean hasSpecification() {
        return (specification != Specification.DEFAULT);
    }

    /**
     * Determines whether the character used to trim the string was specified.
     *
     * @return <code>true</code> if the character used for trimming was specified; <code>false</code>
     * otherwise
     */
    public boolean hasTrimCharacter() {
        return trimCharacter != null &&
              !trimCharacter.isNull();
    }

    @Override
    protected void parseEncapsulatedExpression(WordParser wordParser,
                                               int whitespaceCount,
                                               boolean tolerant) {

        // Parse the trim specification
        specification = parseTrimSpecification(wordParser);

        if (specification != Specification.DEFAULT) {
            specificationIdentifier = wordParser.moveForward(specification.name().length());
            hasSpaceAfterSpecification = wordParser.skipLeadingWhitespace() > 0;
        }

        // Parse the trim character
        if (!wordParser.startsWithIdentifier(FROM)) {
            // Make sure to parse with the encapsulated expression because if it is not
            // the trim character but the string primary, then it has to be parsed correctly
            trimCharacter = parse(wordParser, getEncapsulatedExpressionQueryBNFId(), tolerant);
        }

        if (hasTrimCharacter()) {
            hasSpaceAfterTrimCharacter = wordParser.skipLeadingWhitespace() > 0;
        }

        // Parse 'FROM'
        hasFrom = wordParser.startsWithIdentifier(FROM);

        if (hasFrom) {
            fromIdentifier = wordParser.moveForward(FROM);
            hasSpaceAfterFrom = wordParser.skipLeadingWhitespace() > 0;
        }

        // Parse the string primary
        super.parseEncapsulatedExpression(wordParser, whitespaceCount, tolerant);

        // The trim character is actually the string primary
        if (!hasFrom         &&
            !hasExpression() &&
             hasTrimCharacter()) {

            setExpression(trimCharacter);
            trimCharacter = null;

            if (hasSpaceAfterTrimCharacter) {
                hasSpaceAfterTrimCharacter = false;
                wordParser.moveBackward(1);
            }
        }
    }

    private Specification parseTrimSpecification(WordParser wordParser) {

        if (wordParser.startsWithIdentifier(BOTH)) {
            return Specification.BOTH;
        }

        if (wordParser.startsWithIdentifier(LEADING)) {
            return Specification.LEADING;
        }

        if (wordParser.startsWithIdentifier(TRAILING)) {
            return Specification.TRAILING;
        }

        return Specification.DEFAULT;
    }

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

        // Trim specification
        if (hasSpecification()) {
            writer.append(specification);
        }

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

        // Trim character
        if (hasTrimCharacter()) {
            trimCharacter.toParsedText(writer, actual);
        }

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

        // 'FROM'
        if (hasFrom) {
            writer.append(actual ? fromIdentifier : FROM);
        }

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

        // String primary
        super.toParsedTextEncapsulatedExpression(writer, actual);
    }

    /**
     * The possible ways to trim the string.
     */
    public enum Specification {

        /**
         * The leading and trailing parts of the string will be trimmed.
         */
        BOTH(Expression.BOTH),

        /**
         * Used when the trim specification is not specified, by default it means the leading and
         * trailing parts of the string will be trimmed.
         */
        DEFAULT(ExpressionTools.EMPTY_STRING),

        /**
         * Only the leading part of the string will be trimmed.
         */
        LEADING(Expression.LEADING),

        /**
         * Only the trailing part of the string will be trimmed.
         */
        TRAILING(Expression.TRAILING);

        /**
         * The actual constant associated with the constant.
         */
        private String value;

        private Specification(String value) {
            this.value = value;
        }

        /**
         * Returns the actual identifier associated with the constant.
         *
         * @return The identifier associated with the constant or an empty string for {@link #DEFAULT}
         */
        public String getValue() {
            return value;
        }
    }
}
