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

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.jpa.jpql.parser.Join;
import org.eclipse.persistence.mappings.DatabaseMapping;

/**
 * This <code>RangeDeclaration</code> represents an identification variable declaration that was
 * declared in the <code><b>FROM</b></code> clause of a <code><b>SELECT</b></code> top-level query
 * or subquery.
 *
 * @see org.eclipse.persistence.jpa.jpql.parser.IdentificationVariableDeclaration IdentificationVariableDeclaration
 *
 * @version 2.5
 * @since 2.4
 * @author Pascal Filion
 */
final class RangeDeclaration extends AbstractRangeDeclaration {

    /**
     * The list of <b>JOIN FETCH</b> expressions that are declared in the same declaration than
     * the range variable declaration.
     */
    private List<Join> joinFetches;

    /**
     * If the "root" path is the fully qualified class name, then this will be set.
     */
    public Class<?> type;

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

    @Override
    void addJoin(Join join) {
        super.addJoin(join);

        if (join.hasFetch()) {
            addJoinFetch(join);
        }
    }

    private void addJoinFetch(Join join) {
        if (joinFetches == null) {
            joinFetches = new LinkedList<>();
        }
        joinFetches.add(join);
    }

    @Override
    Expression buildQueryExpression() {

        ClassDescriptor descriptor = getDescriptor();

        // The abstract schema name can't be resolved, we'll assume it's actually an unqualified
        // state field path expression or collection-valued path expression declared in an UPDATE
        // or DELETE query
        if (descriptor == null) {

            // Convert the AbstractSchemaName into a CollectionValuedPathExpression since
            // it's an unqualified state field path expression or collection-valued path expression
            convertUnqualifiedDeclaration();

            // The abstract schema name is now a CollectionValuedPathExpression, request the context
            // to return the Expression for the new Declaration
            return queryContext.getBaseExpression();
        }

        return new ExpressionBuilder(descriptor.getJavaClass());
    }

    /**
     * Converts the given {@link Declaration} from being set as a range variable declaration to
     * a path expression declaration.
     * <p>
     * In this query "{@code UPDATE Employee SET firstName = 'MODIFIED' WHERE (SELECT COUNT(m) FROM
     * managedEmployees m) > 0}" <em>managedEmployees</em> is an unqualified collection-valued
     * path expression (<code>employee.managedEmployees</code>).
     */
    private void convertUnqualifiedDeclaration() {

        // Retrieve the range identification variable from the parent declaration
        Declaration parentDeclaration = queryContext.getParent().getFirstDeclarationImp();
        String outerVariableName = parentDeclaration.getVariableName();

        // Qualify the range expression to be fully qualified
        queryContext.getDeclarationResolver().convertUnqualifiedDeclaration(this, outerVariableName);
    }

    /**
     * Returns the <b>JOIN FETCH</b> expressions that were part of the range variable declaration
     * in the ordered they were parsed.
     *
     * @return The ordered list of <b>JOIN FETCH</b> expressions or an empty collection if none
     * was present
     */
    List<Join> getJoinFetches() {
        return (joinFetches == null) ? Collections.<Join>emptyList() : joinFetches;
    }

    @Override
    public Type getType() {
        return (type != null) ? Type.CLASS_NAME : Type.RANGE;
    }

    /**
     * Determines whether the "root" path is either the abstract schema name (entity name) or the
     * abstract schema name.
     *
     * @return <code>true</code> if it is the fully qualified class name; <code>false</code> if it
     * is the entity name
     */
    public boolean isFullyQualifiedClassName() {
        return type != null;
    }

    @Override
    ClassDescriptor resolveDescriptor() {

        if (type != null) {
            return queryContext.getDescriptor(type);
        }

        return queryContext.getDescriptor(rootPath);
    }

    @Override
    DatabaseMapping resolveMapping() {
        // A range declaration does not have a mapping, only a descriptor
        return null;
    }
}
