/*
 * Copyright (c) 2011, 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.tools.model.query;

import static org.eclipse.persistence.jpa.jpql.parser.AbstractExpression.LEFT_PARENTHESIS;
import static org.eclipse.persistence.jpa.jpql.parser.AbstractExpression.RIGHT_PARENTHESIS;
import static org.eclipse.persistence.jpa.jpql.parser.AbstractExpression.SPACE;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.AS;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.TREAT;

import java.io.IOException;
import java.util.List;

import org.eclipse.persistence.jpa.jpql.parser.TreatExpression;
import org.eclipse.persistence.jpa.jpql.tools.spi.IEntity;

/**
 * Returns an expression that allows to treat its base as if it were a subclass of the class
 * returned by the base.
 * <p>
 * <b>Note:</b> {@link EclipseLinkStateObjectVisitor} needs to be used to traverse this state object.
 * </p>
 * <div><p><b>BNF:</b> <code>join_treat ::= TREAT(collection_valued_path_expression [AS] entity_type_literal)</code></p></div>
 *
 * @see TreatExpression
 *
 * @version 2.4
 * @since 2.4
 * @author Pascal Filion
 */
@SuppressWarnings({"nls"})
public class TreatExpressionStateObject extends AbstractStateObject {

    /**
     * Flag used to determine if the <code><b>AS</b></code> identifier is used or not.
     */
    private boolean as;

    /**
     * The {@link StateObject} representing the entity type name.
     */
    private EntityTypeLiteralStateObject entityTypeName;

    /**
     * Keeps a reference onto the {@link JoinStateObject} since it owns the {@link StateObject}
     * representing the collection-valued path expression.
     */
    private JoinStateObject joinStateObject;

    /**
     * Notifies the visibility of the <code><b>AS</b></code> identifier has changed.
     */
    public static final String AS_PROPERTY = "as";

    /**
     * Notifies the entity type name property has changed.
     */
    public static final String ENTITY_TYPE_NAME_PROPERTY = "entityTypeName";

    /**
     * Creates a new <code>TreatExpressionStateObject</code>.
     *
     * @param parent The parent of this state object, which is temporary since this state object will
     * be parented with the state object representing the join's association path expression
     */
    public TreatExpressionStateObject(JoinStateObject parent) {
        super(parent);
        this.joinStateObject = parent;
    }

    /**
     * Creates a new <code>TreatExpressionStateObject</code>.
     *
     * @param parent The parent of this state object, which is temporary since this state object will
     * be parented with the state object representing the join's association path expression
     * @param as Determines whether the <code><b>AS</b></code> identifier is used or not
     * @param entityTypeName The entity type name used to cast the base expression
     */
    public TreatExpressionStateObject(JoinStateObject parent, boolean as, String entityTypeName) {
        super(parent);
        this.as              = as;
        this.joinStateObject = parent;
        this.entityTypeName.setText(entityTypeName);
    }

    /**
     * Creates a new <code>TreatExpressionStateObject</code>.
     *
     * @param parent The parent of this state object, which is temporary since this state object will
     * be parented with the state object representing the join's association path expression
     * @param entityTypeName The entity type name used to cast the base expression
     */
    public TreatExpressionStateObject(JoinStateObject parent, String entityTypeName) {
        this(parent, false, entityTypeName);
    }

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

    /**
     * Makes sure the <code><b>AS</b></code> identifier is specified.
     *
     * @return This object
     */
    public TreatExpressionStateObject addAs() {
        if (!as) {
            setAs(true);
        }
        return this;
    }

    @Override
    protected void addChildren(List<StateObject> children) {
        super.addChildren(children);
        children.add(entityTypeName);
    }

    /**
     * Appends the given text to the existing entity type name property.
     *
     * @param text The text to append to the entity type name property or nothing is done if the
     * given value is <code>null</code>
     */
    public void appendToEntityTypeName(String text) {
        if (text != null) {
            if (entityTypeName == null) {
                setEntityTypeName(text);
            }
            else {
                setEntityTypeName(entityTypeName + text);
            }
        }
    }

    /**
     * Resolves the entity type name to the external form of the actual {@link IEntity}.
     *
     * @return Either the {@link IEntity} with the same entity type name or <code>null</code> if the
     * managed type provider does not have an entity with that name
     */
    public IEntity getEntity() {
        String entityName = entityTypeName.getText();
        for (IEntity entity : getManagedTypeProvider().entities()) {
            if (entity.getName().equals(entityName)) {
                return entity;
            }
        }

        return null;
    }

    /**
     * Returns the name of the entity that is used to downcast the join association path.
     *
     * @return The name of the entity used for down casting
     */
    public String getEntityTypeName() {
        return entityTypeName.getText();
    }

    @Override
    public TreatExpression getExpression() {
        return (TreatExpression) super.getExpression();
    }

    /**
     * Returns the reference of the {@link JoinStateObject}.
     *
     * @return The "owning" of this object
     */
    public JoinStateObject getJoin() {
        return joinStateObject;
    }

    /**
     * Returns the {@link StateObject} representing the identification variable that starts the path
     * expression, which can be a sample identification variable, a map value, map key or map entry
     * expression.
     *
     * @return The root of the path expression
     */
    public StateObject getJoinAssociationIdentificationVariable() {
        return joinStateObject.getJoinAssociationIdentificationVariable();
    }

    /**
     * Returns the {@link CollectionValuedPathExpressionStateObject} representing the join
     * association path.
     *
     * @return The state object representing the join association path
     */
    public CollectionValuedPathExpressionStateObject getJoinAssociationPathStateObject() {
        return joinStateObject.getJoinAssociationPathStateObject();
    }

    /**
     * Determines whether the <code><b>AS</b></code> identifier is used.
     *
     * @return <code>true</code> if the <code><b>AS</b></code> identifier is used; <code>false</code>
     * otherwise
     */
    public boolean hasAs() {
        return as;
    }

    /**
     * Determines whether the.
     *
     * @return <code>true</code> if the entity type name has been defined; <code>false</code>
     * otherwise
     */
    public boolean hasEntityTypeName() {
        return entityTypeName != null;
    }

    @Override
    protected void initialize() {
        super.initialize();
        entityTypeName = new EntityTypeLiteralStateObject(this);
    }

    @Override
    public boolean isEquivalent(StateObject stateObject) {

        if (super.isEquivalent(stateObject)) {
            TreatExpressionStateObject treat = (TreatExpressionStateObject) stateObject;
            return as == treat.as &&
                   entityTypeName.isEquivalent(treat.entityTypeName);
        }

        return false;
    }

    /**
     * Makes sure the <code><b>AS</b></code> identifier is not specified.
     */
    public void removeAs() {
        if (as) {
            setAs(true);
        }
    }

    /**
     * Sets whether the <code><b>AS</b></code> identifier should be used.
     *
     * @param as <code>true</code> if the <code><b>AS</b></code> identifier should be used part;
     * <code>false</code> otherwise
     */
    public void setAs(boolean as) {
        boolean oldAs = this.as;
        this.as = as;
        firePropertyChanged(AS_PROPERTY, oldAs, as);
    }

    /**
     * Sets the name of the entity that is used to downcast the join association path.
     *
     * @param entityType The Java class representing the entity type
     */
    public void setEntityTypeName(Class<?> entityType) {
        setEntityTypeName(entityType.getName());
    }

    /**
     * Sets the name of the entity that is used to downcast the join association path.
     *
     * @param entityType The external form of the entity type
     */
    public void setEntityTypeName(IEntity entityType) {
        setEntityTypeName(entityType.getName());
    }

    /**
     * Sets the name of the entity that is used to downcast the join association path.
     *
     * @param entityTypeName The new name of the entity used for down casting
     */
    public void setEntityTypeName(String entityTypeName) {
        String oldEntityTypeName = getEntityTypeName();
        this.entityTypeName.setText(entityTypeName);
        firePropertyChanged(ENTITY_TYPE_NAME_PROPERTY, oldEntityTypeName, entityTypeName);
    }

    /**
     * Keeps a reference of the {@link TreatExpression parsed object} object, which should only be
     * done when this object is instantiated during the conversion of a parsed JPQL query into
     * {@link StateObject StateObjects}.
     *
     * @param expression The {@link TreatExpression parsed object} representing the <code><b>TREAD</b></code>
     * expression
     */
    public void setExpression(TreatExpression expression) {
        super.setExpression(expression);
    }

    /**
     * Toggles the visibility of the <code><b>AS</b></code> identifier; either adds it if it's not
     * present otherwise removes it if it's present.
     */
    public void toggleAs() {
        setAs(!as);
    }

    @Override
    protected void toTextInternal(Appendable writer) throws IOException {

        // TREAT
        writer.append(TREAT);

        writer.append(LEFT_PARENTHESIS);

        // Join association path expression
        getJoinAssociationPathStateObject().toTextInternal(writer);

        // AS
        if (as) {
            writer.append(SPACE);
            writer.append(AS);
        }

        // Entity type literal
        if (entityTypeName.hasText()) {
            writer.append(SPACE);
            entityTypeName.toTextInternal(writer);
        }

        writer.append(RIGHT_PARENTHESIS);
    }
}
