/*
 * 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
//
//     09/02/2019-3.0 Alexandre Jacob
//        - 527415: Fix code when locale is tr, az or lt
package org.eclipse.persistence.jpa.jpql.parser;

import java.util.List;
import java.util.Locale;

import org.eclipse.persistence.jpa.jpql.WordParser;

/**
 * An identification variable is a valid identifier declared in the <b>FROM</b> clause of a query.
 * <p>
 * Requirements:
 * <ul>
 * <li>All identification variables must be declared in the <b>FROM</b> clause. Identification
 * variables cannot be declared in other clauses.
 * <li>An identification variable must not be a reserved identifier or have the same name as any
 * entity in the same persistence unit.
 * <li>Identification variables are case insensitive.
 * <li>An identification variable evaluates to a value of the type of the expression used in
 * declaring the variable.
 * </ul>
 * <p>
 * An identification variable can range over an entity, embeddable, or basic abstract schema type.
 * An identification variable designates an instance of an abstract schema type or an element of a
 * collection of abstract schema type instances.
 * <p>
 * Note that for identification variables referring to an instance of an association or collection
 * represented as a {@link java.util.Map}, the identification variable is of the abstract schema
 * type of the map value.
 * <p>
 * An identification variable always designates a reference to a single value. It is declared in one
 * of three ways:
 * <ul>
 * <li>In a range variable declaration;
 * <li>In a join clause;
 * <li>In a collection member declaration.
 * </ul>
 * The identification variable declarations are evaluated from left to right in the <b>FROM</b>
 * clause, and an identification variable declaration can use the result of a preceding
 * identification variable declaration of the query string.
 * <p>
 * All identification variables used in the <b>SELECT</b>, <b>WHERE</b>, <b>ORDER BY</b>,
 * <b>GROUP BY</b>, or <b>HAVING</b> clause of a <b>SELECT</b> or <b>DELETE</b> statement must be
 * declared in the <b>FROM</b> clause. The identification variables used in the <b>WHERE</b> clause
 * of an <b>UPDATE</b> statement must be declared in the <b>UPDATE</b> clause.
 * <p>
 * An identification variable is scoped to the query (or subquery) in which it is defined and is
 * also visible to any subqueries within that query scope that do not define an identification
 * variable of the same name.
 *
 * @version 2.4
 * @since 2.3
 * @author Pascal Filion
 */
public final class IdentificationVariable extends AbstractExpression {

    /**
     * The virtual state field path expression having
     */
    private StateFieldPathExpression stateFieldPathExpression;

    /**
     * The uppercase version of the identification variable.
     */
    private String variableName;

    /**
     * Determines whether this identification variable is virtual, meaning it's not part of the query
     * but is required for proper navigability.
     */
    private boolean virtual;

    /**
     * Creates a new <code>IdentificationVariable</code>.
     *
     * @param parent The parent of this expression
     * @param identificationVariable The actual identification variable
     */
    public IdentificationVariable(AbstractExpression parent, String identificationVariable) {
        super(parent, identificationVariable);
    }

    /**
     * Creates a new <code>IdentificationVariable</code>.
     *
     * @param parent The parent of this expression
     * @param identificationVariable The actual identification variable
     * @param virtual Determines whether this identification variable is virtual, meaning it's not
     * part of the query but is required for proper navigability
     */
    public IdentificationVariable(AbstractExpression parent, String identificationVariable, boolean virtual) {
        super(parent, identificationVariable);
        this.virtual = virtual;
    }

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

    @Override
    public void acceptChildren(ExpressionVisitor visitor) {
        // Nothing to traverse
    }

    @Override
    protected void addOrderedChildrenTo(List<Expression> children) {
        children.add(buildStringExpression(getText()));
    }

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

    /**
     * Returns the actual representation of the parsed information. This method should only be called
     * if {@link #isVirtual()} returns <code>true</code>. This is valid in an <b>UPDATE</b> and
     * <b>DELETE</b> queries where the identification variable is not specified.
     *
     * @return The path expression that is qualified by the virtual identification variable
     * @throws IllegalAccessError If this expression does not have a virtual identification variable
     */
    @SuppressWarnings("nls")
    public StateFieldPathExpression getStateFieldPathExpression() {
        if (!virtual) {
            throw new IllegalAccessError("IdentificationVariable.getStateFieldPathExpression() can only be accessed when it represents an attribute that is not fully qualified, which can be present in an UPDATE or DELETE query.");
        }
        return stateFieldPathExpression;
    }

    @Override
    public String getText() {
        return super.getText();
    }

    /**
     * Returns the identification variable, which has been changed to be upper case.
     *
     * @return The uppercase version of the identification variable
     * @since 2.4
     */
    public String getVariableName() {
        if (variableName == null) {
            variableName = getText().toUpperCase(Locale.ROOT).intern();
        }
        return variableName;
    }

    @Override
    public boolean isVirtual() {
        return virtual;
    }

    @Override
    protected void parse(WordParser wordParser, boolean tolerant) {
        wordParser.moveForward(getText());
    }

    /**
     * Sets a virtual identification variable because the abstract schema name was parsed without
     * one. This is valid in an <b>UPDATE</b> and <b>DELETE</b> queries. This internally transforms
     * the what was thought to be an identification variable to a path expression.
     *
     * @param variableName The identification variable that was generated to identify the "root" object
     */
    public void setVirtualIdentificationVariable(String variableName) {

        virtual = true;

        stateFieldPathExpression = new StateFieldPathExpression(getParent(), getText());
        stateFieldPathExpression.setVirtualIdentificationVariable(variableName);

        rebuildActualText();
        rebuildParsedText();
    }

    @Override
    public String toParsedText() {
        return getText();
    }

    @Override
    protected void toParsedText(StringBuilder writer, boolean actual) {
        writer.append(getText());
    }
}
