/*
 * Copyright (c) 2012, 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.resolver;

import org.eclipse.persistence.jpa.jpql.BaseDeclarationIdentificationVariableFinder;
import org.eclipse.persistence.jpa.jpql.parser.AbstractSchemaName;
import org.eclipse.persistence.jpa.jpql.tools.JPQLQueryContext;
import org.eclipse.persistence.jpa.jpql.tools.spi.IManagedType;
import org.eclipse.persistence.jpa.jpql.tools.spi.IMapping;
import org.eclipse.persistence.jpa.jpql.tools.spi.IType;
import org.eclipse.persistence.jpa.jpql.tools.spi.ITypeDeclaration;

/**
 * This {@link Resolver} retrieves the type for an abstract schema name (entity name) if it can
 * be resolved otherwise a derived path will be assumed. This {@link Resolver} is used within a
 * subquery and it handles the following two cases.
 * <p>
 * The "root" object in the subquery is an unqualified derived path:
 * <pre><code> UPDATE Employee SET name = 'JPQL'
 * WHERE (SELECT a FROM addr a)</code></pre>
 * and
 * The "root" object in the subquery is an entity:
 * <pre><code> UPDATE Employee SET name = 'JPQL'
 * WHERE (SELECT a FROM Address a)</code></pre>
 *
 * @version 2.5
 * @since 2.5
 * @author Pascal Filion
 */
public class SubqueryEntityResolver extends Resolver {

    /**
     * The {@link AbstractSchemaName} holding onto the the name of the entity.
     */
    private AbstractSchemaName abstractSchemaName;

    /**
     * The actual {@link Resolver} when the abstract schema name is actually an unqualified derived
     * path expression.
     */
    private Resolver derivedPathResolver;

    /**
     * The name of the entity or the unqualified derived path.
     */
    private String entityName;

    /**
     * The {@link IManagedType} with the same abstract schema name.
     */
    private IManagedType managedType;

    /**
     * Determines whether the managed type was resolved or not.
     */
    private boolean managedTypeResolved;

    /**
     * The {@link JPQLQueryContext} for the subquery.
     */
    private JPQLQueryContext queryContext;

    /**
     * Creates a new <code>DerivedPathResolver</code>.
     *
     * @param parent The parent {@link Resolver}, which is never <code>null</code>
     * @param queryContext The {@link JPQLQueryContext} for the subquery
     * @param abstractSchemaName The {@link AbstractSchemaName} holding onto the the name of the entity
     */
    public SubqueryEntityResolver(Resolver parent,
                                  JPQLQueryContext queryContext,
                                  AbstractSchemaName abstractSchemaName) {

        super(parent);
        this.queryContext       = queryContext;
        this.abstractSchemaName = abstractSchemaName;
        this.entityName         = abstractSchemaName.getText();
    }

    @Override
    protected IType buildType() {
        IManagedType entity = getManagedType();
        return (entity != null) ? entity.getType() : getTypeHelper().objectType();
    }

    @Override
    protected ITypeDeclaration buildTypeDeclaration() {
        return getType().getTypeDeclaration();
    }

    /**
     * Returns the name of the entity to resolve.
     *
     * @return The entity name, which is never <code>null</code>
     */
    public String getAbstractSchemaName() {
        return entityName;
    }

    @Override
    public IManagedType getManagedType() {

        if ((managedType == null) && !managedTypeResolved) {

            managedTypeResolved = true;
            managedType = getProvider().getEntityNamed(entityName);

            if (managedType == null) {
                Resolver resolver = resolveDerivePathResolver();
                managedType = resolver.getManagedType();
            }
        }

        return managedType;
    }

    @Override
    public IMapping getMapping() {

        if (derivedPathResolver != null) {
            return derivedPathResolver.getMapping();
        }

        // The managed type cannot be resolved and this is for a subquery,
        // attempt to resolve an unqualified derived path expression
        if ((getManagedType() == null) && queryContext.isSubquery()) {
            Resolver resolver = resolveDerivePathResolver();
            return resolver.getMapping();
        }

        return super.getMapping();
    }

    /**
     * Creates the {@link Resolver} for a unqualified derived path expression.
     *
     * @return A non-<code>null</code> {@link Resolver}
     */
    protected Resolver resolveDerivePathResolver() {

        if (derivedPathResolver == null) {

            // Retrieve the identification variable of the top-level query's base declaration
            BaseDeclarationIdentificationVariableFinder finder = new BaseDeclarationIdentificationVariableFinder();
            abstractSchemaName.accept(finder);

            if (finder.expression != null) {

                // Retrieve the Resolver for the identification variable
                DeclarationResolver parent = queryContext.getParent().getActualDeclarationResolver();
                Resolver resolver = parent.getResolver(finder.expression.getVariableName());

                // Retrieve the Resolver for the unqualified path expression
                Resolver childResolver = resolver.getChild(entityName);

                if (childResolver == null) {
                    childResolver = new StateFieldResolver(resolver, entityName);
                }

                derivedPathResolver = childResolver;
            }

            // Invalid query/subquery
            if (derivedPathResolver == null) {
                derivedPathResolver = new NullResolver(this);
            }
        }

        return derivedPathResolver;
    }

    @Override
    public String toString() {
        return entityName;
    }
}
