/*
 * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2021 IBM Corporation. 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 static org.eclipse.persistence.jpa.jpql.LiteralType.PATH_EXPRESSION_LAST_PATH;
import static org.eclipse.persistence.jpa.jpql.LiteralType.RESULT_VARIABLE;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.parser.AbsExpression;
import org.eclipse.persistence.jpa.jpql.parser.AbstractEclipseLinkExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AdditionExpression;
import org.eclipse.persistence.jpa.jpql.parser.AvgFunction;
import org.eclipse.persistence.jpa.jpql.parser.CollectionExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConcatExpression;
import org.eclipse.persistence.jpa.jpql.parser.CountFunction;
import org.eclipse.persistence.jpa.jpql.parser.DivisionExpression;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
import org.eclipse.persistence.jpa.jpql.parser.IndexExpression;
import org.eclipse.persistence.jpa.jpql.parser.LengthExpression;
import org.eclipse.persistence.jpa.jpql.parser.LocateExpression;
import org.eclipse.persistence.jpa.jpql.parser.LowerExpression;
import org.eclipse.persistence.jpa.jpql.parser.MaxFunction;
import org.eclipse.persistence.jpa.jpql.parser.MinFunction;
import org.eclipse.persistence.jpa.jpql.parser.ResultVariable;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectClause;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.SizeExpression;
import org.eclipse.persistence.jpa.jpql.parser.SqrtExpression;
import org.eclipse.persistence.jpa.jpql.parser.StateFieldPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.SubstringExpression;
import org.eclipse.persistence.jpa.jpql.parser.SubtractionExpression;
import org.eclipse.persistence.jpa.jpql.parser.SumFunction;
import org.eclipse.persistence.jpa.jpql.parser.TrimExpression;
import org.eclipse.persistence.jpa.jpql.parser.UpperExpression;
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.IManagedTypeProvider;
import org.eclipse.persistence.jpa.jpql.tools.spi.IManagedTypeVisitor;
import org.eclipse.persistence.jpa.jpql.tools.spi.IMapping;
import org.eclipse.persistence.jpa.jpql.tools.spi.IMappingType;
import org.eclipse.persistence.jpa.jpql.tools.spi.IType;
import org.eclipse.persistence.jpa.jpql.tools.spi.ITypeDeclaration;
import org.eclipse.persistence.jpa.jpql.tools.utility.iterable.SnapshotCloneIterable;

/**
 * This {@link Resolver} wraps a subquery that is used as the "root" object in a query's declaration.
 * <p>
 * Example:
 *
 * <pre><code>   SELECT e.firstName
 * FROM Employee e, (SELECT count(e2), e2.firstName FROM Employee e2) e3
 * WHERE e.firstName = e3.firstName</code></pre>
 *
 * @version 2.5
 * @since 2.4
 * @author Pascal Filion
 */
public class FromSubqueryResolver extends Resolver {

    /**
     * The virtual {@link IManagedType} representing the subquery.
     */
    private IManagedType managedType;

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

    /**
     * The subquery being defined as a "root" object.
     */
    private SimpleSelectStatement subquery;

    /**
     * Creates a new <code>FromSubqueryResolver</code>.
     *
     * @param parent The parent of this resolver, which is never <code>null</code>
     * @param queryContext The context used to query information about the application metadata and
     * cached information
     * @param subquery
     * @exception NullPointerException If the parent is <code>null</code>
     */
    public FromSubqueryResolver(Resolver parent,
                                JPQLQueryContext queryContext,
                                SimpleSelectStatement subquery) {

        super(parent);
        this.subquery     = subquery;
        this.queryContext = queryContext;
    }

    @Override
    protected IType buildType() {
        return getManagedType().getType();
    }

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

    @Override
    public IManagedType getManagedType() {
        if (managedType == null) {
            managedType = new VirtualManagedType();
        }
        return managedType;
    }

    private enum MappingType {
        PROPERTY,
        RELATIONSHIP,
        UNKNOWN
    }

    /**
     * This {@link IManagedType} represents a virtual managed type where its content will be derived
     * from the subquery.
     */
    protected class VirtualManagedType implements IManagedType {

        /**
         * The virtual {@link IMapping mappings} representing what is selected.
         */
        private Map<String, IMapping> mappings;

        @Override
        public void accept(IManagedTypeVisitor visitor) {
        }

        @Override
        public int compareTo(IManagedType managedType) {
            return getType().getName().compareTo(managedType.getType().getName());
        }

        @Override
        public IMapping getMappingNamed(String name) {
            initializeMappings();
            return mappings.get(name);
        }

        @Override
        public IManagedTypeProvider getProvider() {
            return FromSubqueryResolver.this.getProvider();
        }

        @Override
        public IType getType() {
            return getProvider().getTypeRepository().getType(IType.UNRESOLVABLE_TYPE);
        }

        private void initializeMappings() {

            if (mappings == null) {
                mappings = new HashMap<String, IMapping>();

                // Create virtual mappings that wraps the select items
                VirtualMappingBuilder builder = new VirtualMappingBuilder();
                builder.parent   = this;
                builder.mappings = mappings;

                subquery.accept(builder);
            }
        }

        @Override
        public Iterable<IMapping> mappings() {
            initializeMappings();
            return new SnapshotCloneIterable<IMapping>(mappings.values());
        }
    }

    /**
     * This virtual {@link IMapping} wraps one of the select items.
     */
    protected static class VirtualMapping implements IMapping {

        private MappingType mappingType;
        private String name;
        private IManagedType parent;
        private Resolver resolver;

        protected VirtualMapping(IManagedType parent,
                                 String name,
                                 Resolver resolver,
                                 MappingType mappingType) {

            super();
            this.name        = name;
            this.parent      = parent;
            this.resolver    = resolver;
            this.mappingType = mappingType;
        }

        @Override
        public int compareTo(IMapping mapping) {
            return getName().compareTo(mapping.getName());
        }

        @Override
        public int getMappingType() {
            IMapping mapping = resolver.getMapping();
            return (mapping != null) ? mapping.getMappingType() : IMappingType.TRANSIENT;
        }

        @Override
        public String getName() {
            return name;
        }

        @Override
        public IManagedType getParent() {
            return parent;
        }

        @Override
        public IType getType() {
            return resolver.getType();
        }

        @Override
        public ITypeDeclaration getTypeDeclaration() {
            return resolver.getTypeDeclaration();
        }

        @Override
        public boolean hasAnnotation(Class<? extends Annotation> annotationType) {
            // TODO: Can we do this???
            return getType().hasAnnotation(annotationType);
        }

        @Override
        public boolean isCollection() {
            IMapping mapping = resolver.getMapping();
            return (mapping != null) ? mapping.isCollection() : false;
        }

        @Override
        public boolean isEmbeddable() {
            IMapping mapping = resolver.getMapping();
            return (mapping != null) ? mapping.isEmbeddable() : false;
        }

        @Override
        public boolean isProperty() {
            IMapping mapping = resolver.getMapping();
            return (mapping != null) ? mapping.isProperty() : (mappingType == MappingType.PROPERTY);
        }

        @Override
        public boolean isRelationship() {
            IMapping mapping = resolver.getMapping();
            return (mapping != null) ? mapping.isRelationship() : (mappingType == MappingType.RELATIONSHIP);
        }

        @Override
        public boolean isTransient() {
            IMapping mapping = resolver.getMapping();
            return (mapping != null) ? mapping.isTransient() : false;
        }

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

    /**
     * This visitor will traverse the <code><b>SELECT</b></code> clause and create virtual mappings
     * for the state field path expressions and any expression aliased with a result variable.
     */
    protected class VirtualMappingBuilder extends AbstractEclipseLinkExpressionVisitor {

        /**
         * The virtual {@link IMapping} that wraps a select item mapped with the result variable if
         * one was defined otherwise the name will be generated based on the type of select item.
         */
        private Map<String, IMapping> mappings;

        /**
         *
         */
        private MappingType mappingType;

        /**
         * The virtual {@link IManagedType}.
         */
        protected IManagedType parent;

        /**
         * Creates a new <code>VirtualMappingBuilder</code>.
         */
        public VirtualMappingBuilder() {
            super();
            mappingType = MappingType.UNKNOWN;
        }

        /**
         * Creates
         *
         * @param name
         * @param resolver
         * @return
         */
        protected IMapping buildMapping(String name, Resolver resolver) {
            return new VirtualMapping(parent, name, resolver, mappingType);
        }

        @Override
        public void visit(AbsExpression expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(AdditionExpression expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(AvgFunction expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(CollectionExpression expression) {
            expression.acceptChildren(this);
        }

        @Override
        public void visit(ConcatExpression expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(CountFunction expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(DivisionExpression expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(IndexExpression expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(LengthExpression expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(LocateExpression expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(LowerExpression expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(MaxFunction expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(MinFunction expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(ResultVariable expression) {

            String name = queryContext.literal(expression, RESULT_VARIABLE);

            if (ExpressionTools.stringIsNotEmpty(name)) {

                // Visit the select expression in order to get a mapping type that could
                // help determine the mapping type
                Expression selectExpression = expression.getSelectExpression();
                selectExpression.accept(this);

                // Retrieve the select expression's Resolver and wrap it with a virtual mapping
                Resolver resolver = queryContext.getResolver(selectExpression);
                mappings.put(name, buildMapping(name, resolver));
            }
        }

        @Override
        public void visit(SimpleSelectClause expression) {
            expression.getSelectExpression().accept(this);
        }

        @Override
        public void visit(SimpleSelectStatement expression) {
            expression.getSelectClause().accept(this);
        }

        @Override
        public void visit(SizeExpression expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(SqrtExpression expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(StateFieldPathExpression expression) {

            if (!expression.startsWithDot()) {
                String name = queryContext.literal(expression, PATH_EXPRESSION_LAST_PATH);

                if (ExpressionTools.stringIsNotEmpty(name)) {

                    mappingType = MappingType.UNKNOWN;

                    Resolver resolver = queryContext.getResolver(expression);
                    mappings.put(name, buildMapping(name, resolver));
                }
            }
        }

        @Override
        public void visit(SubstringExpression expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(SubtractionExpression expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(SumFunction expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(TrimExpression expression) {
            mappingType = MappingType.PROPERTY;
        }

        @Override
        public void visit(UpperExpression expression) {
            mappingType = MappingType.PROPERTY;
        }
    }
}
