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

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.jpa.jpql.Assert;
import org.eclipse.persistence.jpa.jpql.parser.AbstractEclipseLinkTraverseChildrenVisitor;
import org.eclipse.persistence.jpa.jpql.parser.DefaultEclipseLinkJPQLGrammar;
import org.eclipse.persistence.jpa.jpql.parser.DeleteClause;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
import org.eclipse.persistence.jpa.jpql.parser.FromClause;
import org.eclipse.persistence.jpa.jpql.parser.JPQLExpression;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.UpdateClause;
import org.eclipse.persistence.queries.DatabaseQuery;

/**
 * This helper can perform various operations over a JPQL query.
 *
 * @version 2.5
 * @since 2.5
 * @author Pascal Filion
 */
public class JPQLQueryHelper {

    /**
     * The grammar that defines how to parse a JPQL query.
     */
    private JPQLGrammar jpqlGrammar;

    /**
     * Creates a new <code>JPQLQueryHelper</code> which uses the latest JPQL grammar.
     */
    public JPQLQueryHelper() {
        this(DefaultEclipseLinkJPQLGrammar.instance());
    }

    /**
     * Creates a new <code>JPQLQueryHelper</code>.
     *
     * @param jpqlGrammar The {@link JPQLGrammar} that will determine how to parse JPQL queries
     * @exception NullPointerException The {@link JPQLGrammar} cannot be <code>null</code>
     */
    public JPQLQueryHelper(JPQLGrammar jpqlGrammar) {
        super();
        Assert.isNotNull(jpqlGrammar, "The JPQLGrammar cannot be null");
        this.jpqlGrammar = jpqlGrammar;
    }

    /**
     * Retrieves the list of {@link ClassDescriptor descriptors} corresponding to the entities used
     * throughout the given JPQL query.
     *
     * @param jpqlQuery The JPQL query used to gather the descriptors defined in the declaration clause
     * @param session The {@link AbstractSession} is used to retrieve the descriptors
     * @return The list of {@link ClassDescriptor descriptors} used in the JPQL query or an empty
     * list if the JPQL query is invalid or incomplete
     */
    public List<ClassDescriptor> getClassDescriptors(CharSequence jpqlQuery, AbstractSession session) {

        // Parse the JPQL query
        JPQLExpression jpqlExpression = new JPQLExpression(jpqlQuery, jpqlGrammar, true);

        // Create the context and cache the information
        JPQLQueryContext queryContext = new JPQLQueryContext(jpqlGrammar);
        queryContext.cache(session, null, jpqlExpression, jpqlQuery);

        // Visit the JPQL query and collect the descriptors defined in the declaration clauses
        DescriptorCollector collector = new DescriptorCollector(queryContext);
        jpqlExpression.accept(collector);

        return new ArrayList<>(collector.descriptors);
    }

    /**
     * Retrieves the class names and the attribute names mapped to their types that are used in the
     * constructor expressions defined in the <code><b>SELECT</b></code> clause.
     * <br>
     * For instance, from the following JPQL query:
     * <br>
     * <pre><code> SELECT new test.example.Employee(e.name, e.id),
     *        new test.example.Address(a.zipcode)
     * FROM Employee e, Address a</code></pre>
     * <br>
     * The return object is
     * <pre><code> |- test.example.Employee
     * |-   |- name : String
     * |-   |- id : int
     * |- test.example.Address
     *      |- zipcode : int</code></pre>
     *
     * @param session The {@link AbstractSession} is used to retrieve the mappings used in the
     * constructor items
     * @return The holder of the result
     */
    public List<ConstructorQueryMappings> getConstructorQueryMappings(AbstractSession session) {

        List<ConstructorQueryMappings> allMappings = new LinkedList<>();

        for (DatabaseQuery query : session.getJPAQueries()) {
            ConstructorQueryMappings mappings = getConstructorQueryMappings(session, query);
            allMappings.add(mappings);
        }

        return allMappings;
    }

    /**
     * Retrieves the class names and the attribute names mapped to their types that are used in the
     * constructor expressions defined in the <code><b>SELECT</b></code> clause.
     * <p>
     * For instance, from the following JPQL query:
     * <br>
     * <pre><code> SELECT new test.example.Address(a.streetName, a.zipcode)
     * FROM Address a</code></pre>
     * <br>
     * The return object is
     * <pre><code> test.example.Address
     *    |- BasicMapping(streetName) : String
     *    |- BasicMapping(zipcode) : int</code></pre>
     *
     * @param session The {@link AbstractSession} is used to retrieve the mappings used in the
     * constructor items
     * @return The holder of the result
     */
    public ConstructorQueryMappings getConstructorQueryMappings(AbstractSession session,
                                                                DatabaseQuery query) {

        JPQLQueryContext queryContext = new JPQLQueryContext(query, jpqlGrammar);

        ConstructorQueryMappings mappings = new ConstructorQueryMappings(query);
        mappings.populate(jpqlGrammar);
        return mappings;
    }

    /**
     * Returns the JPQL grammar that will be used to define how to parse a JPQL query.
     *
     * @return The grammar that will determine how to parse a JPQL query
     */
    public JPQLGrammar getGrammar() {
        return jpqlGrammar;
    }

    private static class DescriptorCollector extends AbstractEclipseLinkTraverseChildrenVisitor {

        private Set<ClassDescriptor> descriptors;
        private JPQLQueryContext queryContext;
        private DeclarationResolver resolver;

        /**
         * Creates a new <code>DescriptorCollector</code>.
         */
        private DescriptorCollector(JPQLQueryContext queryContext) {
            super();
            this.descriptors  = new HashSet<>();
            this.queryContext = queryContext;
        }

        private void collectDescriptors(Expression expression, DeclarationResolver resolver) {

            resolver.populate(expression);

            for (Declaration declaration : resolver.getDeclarations()) {
                ClassDescriptor descriptor = declaration.getDescriptor();
                if (descriptor != null) {
                    descriptors.add(descriptor);
                }
            }
        }

        @Override
        public void visit(DeleteClause expression) {
            resolver = new DeclarationResolver(queryContext, null);
            collectDescriptors(expression, resolver);
        }

        @Override
        public void visit(FromClause expression) {
            resolver = new DeclarationResolver(queryContext, null);
            collectDescriptors(expression, resolver);
        }

        @Override
        public void visit(SimpleSelectStatement expression) {
            resolver = new DeclarationResolver(queryContext, resolver);
            collectDescriptors(expression, resolver);
            resolver = resolver.getParent();
        }

        @Override
        public void visit(UpdateClause expression) {
            resolver = new DeclarationResolver(queryContext, null);
            collectDescriptors(expression, resolver);
        }
    }
}
