/*
 * 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.internal.jpa.jpql;

import java.util.Collections;
import java.util.List;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.JPQLQueryDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.AbstractExpression;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable;
import org.eclipse.persistence.jpa.jpql.parser.Join;
import org.eclipse.persistence.mappings.DatabaseMapping;

/**
 * A <code>Declaration</code> is the corresponding representation of a single declaration defined in
 * the <code><b>FROM</b></code> clause of a query.
 *
 * @version 2.5
 * @since 2.4
 * @author Pascal Filion
 */
abstract class Declaration implements JPQLQueryDeclaration {

    /**
     * TODO.
     */
    Expression baseExpression;

    /**
     * The declaration expression, which is either an
     * {@link org.eclipse.persistence.jpa.jpql.parser.IdentificationVariableDeclaration IdentificationVariableDeclaration}
     * or a {@link org.eclipse.persistence.jpa.jpql.parser.CollectionMemberDeclaration CollectionMemberDeclaration}
     * when part of a <b>FROM</b> clause, otherwise it's either the
     * {@link org.eclipse.persistence.jpa.jpql.parser.DeleteClause DeleteClause} or the
     * {@link org.eclipse.persistence.jpa.jpql.parser.UpdateClause UpdateClause}.
     */
    Expression declarationExpression;

    /**
     * The cached {@link ClassDescriptor} that represents this {@link Declaration}'s "root" path.
     */
    private ClassDescriptor descriptor;

    /**
     * The {@link IdentificationVariable} used to declare a "root" object.
     */
    IdentificationVariable identificationVariable;

    /**
     * The cached {@link DatabaseMapping} if this {@link Declaration}'s "root" path points to a
     * mapping, otherwise it will be <code>null</code>.
     */
    private DatabaseMapping mapping;

    /**
     * The {@link JPQLQueryContext} is used to query information about the application metadata and
     * cached information.
     */
    final JPQLQueryContext queryContext;

    /**
     * The {@link org.eclipse.persistence.expressions.Expression Expression} representing the
     * information of this {@link Declaration}.
     */
    private org.eclipse.persistence.expressions.Expression queryExpression;

    /**
     * The "root" object for objects which may not be reachable by navigation, it is either the
     * abstract schema name (entity name), a derived path expression (which is only defined in a
     * subquery) or <code>null</code> if this {@link Declaration} is a collection member declaration.
     */
    String rootPath;

    /**
     * Creates a new <code>Declaration</code>.
     *
     * @param queryContext The context used to query information about the application metadata and
     * cached information
     */
    Declaration(JPQLQueryContext queryContext) {
        super();
        this.queryContext = queryContext;
    }

    /**
     * Creates the Expression {@link Expression} for this {@link Declaration}.
     *
     * @return A new {@link org.eclipse.persistence.expressions.Expression Expression}
     */
    abstract org.eclipse.persistence.expressions.Expression buildQueryExpression();

    @Override
    public Expression getBaseExpression() {
        return baseExpression;
    }

    @Override
    public Expression getDeclarationExpression() {
        return declarationExpression;
    }

    /**
     * Returns the {@link ClassDescriptor} that represents this {@link Declaration}'s "root" path.
     *
     * @return The descriptor of the "root" path
     */
    final ClassDescriptor getDescriptor() {
        if (descriptor == null) {
            descriptor = resolveDescriptor();
        }
        return descriptor;
    }

    @Override
    public List<Join> getJoins() {
        return Collections.emptyList();
    }

    /**
     * Returns the {@link DatabaseMapping} that this {@link Declaration} represents, which may be
     * <code>null</code> in the case it does not represent one.
     *
     * @return Either the {@link DatabaseMapping} of the "root" path, or <code>null</code> if the
     * "root" path is not a mapping
     */
    final DatabaseMapping getMapping() {
        if (mapping == null) {
            mapping = resolveMapping();
        }
        return mapping;
    }

    /**
     * Returns the Expression {@link Expression} for this {@link Declaration}.
     *
     * @return The {@link org.eclipse.persistence.expressions.Expression Expression} representing the
     * information of this {@link Declaration}
     */
    final org.eclipse.persistence.expressions.Expression getQueryExpression() {

        if (queryExpression == null) {

            // First create the Expression
            queryExpression = buildQueryExpression();

            // Cache the base expression with its identification variable as well
            queryContext.addQueryExpressionImp(getVariableName(), queryExpression);
        }

        return queryExpression;
    }

    @Override
    public final String getVariableName() {
        if (identificationVariable == null) {
            return ExpressionTools.EMPTY_STRING;
        }
        return identificationVariable.getVariableName();
    }

    @Override
    public boolean hasJoins() {
        return false;
    }

    /**
     * Resolves this {@link Declaration} and returns the associated {@link ClassDescriptor}. For a
     * {@link org.eclipse.persistence.jpa.jpql.parser.RangeVariableDeclaration}, this will return the actual descriptor for the entity. For
     * a mapping, this will return the reference descriptor.
     *
     * @return The descriptor associated with this declaration
     */
    abstract ClassDescriptor resolveDescriptor();

    /**
     * Resolves this {@link Declaration} and returns the associated {@link DatabaseMapping} if this
     * represents a path expression. In the case of a {@link org.eclipse.persistence.jpa.jpql.parser.RangeVariableDeclaration}, this will
     * return <code>null</code>.
     *
     * @return The mapping associated with this declaration
     */
    abstract DatabaseMapping resolveMapping();

    @Override
    public String toString() {

        if (declarationExpression != null) {
            return declarationExpression.toParsedText();
        }

        StringBuilder sb = new StringBuilder();
        sb.append(rootPath);

        if (identificationVariable != null) {
            sb.append(AbstractExpression.SPACE);
            sb.append(identificationVariable.getText());
        }

        return sb.toString();
    }
}
