/*
 * 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;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.persistence.jpa.jpql.Assert;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.ITypeHelper;
import org.eclipse.persistence.jpa.jpql.JPQLQueryDeclaration;
import org.eclipse.persistence.jpa.jpql.SemanticValidatorHelper;
import org.eclipse.persistence.jpa.jpql.parser.AbstractExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar;
import org.eclipse.persistence.jpa.jpql.parser.Join;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectStatement;
import org.eclipse.persistence.jpa.jpql.tools.resolver.Declaration;
import org.eclipse.persistence.jpa.jpql.tools.resolver.DeclarationResolver;
import org.eclipse.persistence.jpa.jpql.tools.resolver.Resolver;
import org.eclipse.persistence.jpa.jpql.tools.resolver.StateFieldResolver;
import org.eclipse.persistence.jpa.jpql.tools.spi.IConstructor;
import org.eclipse.persistence.jpa.jpql.tools.spi.IEntity;
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;
import org.eclipse.persistence.jpa.jpql.utility.CollectionTools;

/**
 * An implementation of {@link SemanticValidatorHelper} that uses {@link JPQLQueryContext} to return
 * the required information and Hermes SPI.
 * <p>
 * Provisional API: This interface is part of an interim API that is still under development and
 * expected to change significantly before reaching stability. It is available at this early stage
 * to solicit feedback from pioneering adopters on the understanding that any code that uses this
 * API will almost certainly be broken (repeatedly) as the API evolves.
 *
 * @version 2.5
 * @since 2.4
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public class GenericSemanticValidatorHelper implements SemanticValidatorHelper {

    private IdentificationVariableVisitor identificationVariableVisitor;

    /**
     * The context used to query information about the JPQL query.
     */
    private final JPQLQueryContext queryContext;

    /**
     * The concrete instance of {@link ITypeHelper} that simply wraps {@link TypeHelper}.
     */
    private ITypeHelper typeHelper;

    /**
     * Creates a new <code>GenericSemanticValidatorHelper</code>.
     *
     * @param queryContext The context used to query information about the JPQL query
     * @exception NullPointerException The given {@link JPQLQueryContext} cannot be <code>null</code>
     */
    public GenericSemanticValidatorHelper(JPQLQueryContext queryContext) {
        super();
        Assert.isNotNull(queryContext, "The JPQLQueryContext cannot be null");
        this.queryContext = queryContext;
    }

    protected void addIdentificationVariable(IdentificationVariable identificationVariable,
                                             Map<String, List<IdentificationVariable>> identificationVariables) {

        String variableName = (identificationVariable != null) ? identificationVariable.getVariableName() : null;

        if (ExpressionTools.stringIsNotEmpty(variableName)) {

            // Add the IdentificationVariable to the list
            List<IdentificationVariable> variables = identificationVariables.get(variableName);

            if (variables == null) {
                variables = new ArrayList<IdentificationVariable>();
                identificationVariables.put(variableName, variables);
            }

            variables.add(identificationVariable);
        }
    }

    protected IdentificationVariableVisitor buildIdentificationVariableVisitor() {
        return new IdentificationVariableVisitor();
    }

    @Override
    public void collectAllDeclarationIdentificationVariables(Map<String, List<IdentificationVariable>> identificationVariables) {

        JPQLQueryContext currentContext = queryContext.getCurrentContext();

        while (currentContext != null) {
            collectLocalDeclarationIdentificationVariables(currentContext, identificationVariables);
            currentContext = currentContext.getParent();
        }
    }

    protected void collectLocalDeclarationIdentificationVariables(JPQLQueryContext queryContext,
                                                                  Map<String, List<IdentificationVariable>> identificationVariables) {

        DeclarationResolver declarationResolver = queryContext.getDeclarationResolverImp();

        for (Declaration declaration : declarationResolver.getDeclarations()) {

            // Register the identification variable from the base expression
            IdentificationVariable identificationVariable = declaration.getIdentificationVariable();
            addIdentificationVariable(identificationVariable, identificationVariables);

            // Register the identification variable from the JOIN expressions
            for (Join join : declaration.getJoins()) {
                IdentificationVariable joinIdentificationVariable = getIdentificationVariable(join.getIdentificationVariable());
                addIdentificationVariable(joinIdentificationVariable, identificationVariables);
            }
        }

        if (queryContext.getParent() == null) {
            for (IdentificationVariable identificationVariable : declarationResolver.getResultVariablesMap().keySet()) {
                addIdentificationVariable(identificationVariable, identificationVariables);
            }
        }
    }

    @Override
    public void collectLocalDeclarationIdentificationVariables(Map<String, List<IdentificationVariable>> identificationVariables) {
        collectLocalDeclarationIdentificationVariables(queryContext.getCurrentContext(), identificationVariables);
    }

    @Override
    public void disposeSubqueryContext() {
        queryContext.disposeSubqueryContext();
    }

    @Override
    public String[] entityNames() {

        List<String> names = new ArrayList<String>();

        for (IEntity entity : queryContext.getProvider().entities()) {
            names.add(entity.getName());
        }

        return names.toArray(new String[names.size()]);
    }

    @Override
    public List<JPQLQueryDeclaration> getAllDeclarations() {

        List<JPQLQueryDeclaration> declarations = new ArrayList<JPQLQueryDeclaration>();
        JPQLQueryContext context = queryContext.getCurrentContext();

        while (context != null) {
            declarations.addAll(context.getDeclarationResolverImp().getDeclarations());
            context = context.getParent();
        }

        return declarations;
    }

    @Override
    public IConstructor[] getConstructors(Object type) {
        return CollectionTools.array(IConstructor.class, ((IType) type).constructors());
    }

    @Override
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public List getDeclarations() {
        return queryContext.getDeclarations();
    }

    @Override
    public IManagedType getEmbeddable(Object type) {
        return queryContext.getProvider().getEmbeddable((IType) type);
    }

    @Override
    public IEntity getEntityNamed(String entityName) {
        return queryContext.getProvider().getEntityNamed(entityName);
    }

    @Override
    public String[] getEnumConstants(Object type) {
        return ((IType) type).getEnumConstants();
    }

    @Override
    public JPQLGrammar getGrammar() {
        return queryContext.getGrammar();
    }

    protected IdentificationVariable getIdentificationVariable(Expression expression) {
        IdentificationVariableVisitor visitor = getIdentificationVariableVisitor();
        expression.accept(visitor);
        try {
            return visitor.identificationVariable;
        }
        finally {
            visitor.identificationVariable = null;
        }
    }

    protected IdentificationVariableVisitor getIdentificationVariableVisitor() {
        if (identificationVariableVisitor == null) {
            identificationVariableVisitor = buildIdentificationVariableVisitor();
        }
        return identificationVariableVisitor;
    }

    @Override
    public IManagedType getManagedType(Expression expression) {
        return queryContext.getResolver(expression).getManagedType();
    }

    @Override
    public IMapping getMappingNamed(Object managedType, String path) {
        return ((IManagedType) managedType).getMappingNamed(path);
    }

    @Override
    public IType getMappingType(Object mapping) {
        return (mapping != null) ? ((IMapping) mapping).getType() : queryContext.getTypeHelper().unknownType();
    }

    @Override
    public ITypeDeclaration[] getMethodParameterTypeDeclarations(Object constructor) {
        return ((IConstructor) constructor).getParameterTypes();
    }

    /**
     * Returns the context used to query information about the JPQL query.
     *
     * @return The context used to query information about the JPQL query
     */
    public JPQLQueryContext getQueryContext() {
        return queryContext;
    }

    @Override
    public IManagedType getReferenceManagedType(Object relationshipMapping) {

        if (relationshipMapping == null) {
            return null;
        }

        IMapping mapping = (IMapping) relationshipMapping;
        return mapping.getParent().getProvider().getManagedType(mapping.getType());
    }

    @Override
    public IType getType(Expression expression) {
        return queryContext.getType(expression);
    }

    @Override
    public IType getType(Object typeDeclaration) {
        return ((ITypeDeclaration) typeDeclaration).getType();
    }

    @Override
    public IType getType(String typeName) {
        return queryContext.getType(typeName);
    }

    @Override
    public ITypeDeclaration getTypeDeclaration(Expression expression) {
        return queryContext.getTypeDeclaration(expression);
    }

    @Override
    public ITypeHelper getTypeHelper() {
        if (typeHelper == null) {
            typeHelper = new GenericTypeHelper(queryContext.getTypeHelper());
        }
        return typeHelper;
    }

    @Override
    public String getTypeName(Object type) {
        return ((IType) type).getName();
    }

    @Override
    public boolean isAssignableTo(Object type1, Object type2) {
        return ((IType) type1).isAssignableTo((IType) type2) ;
    }

    @Override
    public boolean isCollectionIdentificationVariable(String variableName) {
        return queryContext.isCollectionIdentificationVariable(variableName);
    }

    @Override
    public boolean isCollectionMapping(Object mapping) {
        return (mapping != null) && ((IMapping) mapping).isCollection();
    }

    @Override
    public boolean isEmbeddableMapping(Object mapping) {
        return (mapping != null) && ((IMapping) mapping).isEmbeddable();
    }

    @Override
    public boolean isEnumType(Object type) {
        return ((IType) type).isEnum();
    }

    @Override
    public boolean isIdentificationVariableValidInComparison(IdentificationVariable expression) {
        return false;
    }

    @Override
    public boolean isManagedTypeResolvable(Object managedType) {
        return ((IManagedType) managedType).getType().isResolvable();
    }

    @Override
    public boolean isPropertyMapping(Object mapping) {
        return (mapping != null) && ((IMapping) mapping).isProperty();
    }

    @Override
    public boolean isRelationshipMapping(Object mapping) {
        return (mapping != null) && ((IMapping) mapping).isRelationship();
    }

    @Override
    public boolean isResultVariable(String variableName) {
        return queryContext.isResultVariable(variableName);
    }

    @Override
    public boolean isTransient(Object mapping) {
        return (mapping != null) && ((IMapping) mapping).isTransient();
    }

    @Override
    public boolean isTypeDeclarationAssignableTo(Object typeDeclaration1, Object typeDeclaration2) {

        ITypeDeclaration declaration1 = (ITypeDeclaration) typeDeclaration1;
        ITypeDeclaration declaration2 = (ITypeDeclaration) typeDeclaration2;

        // One is an array but not the other one
        if (declaration1.isArray() && !declaration2.isArray() ||
           !declaration1.isArray() &&  declaration2.isArray()) {

            return false;
        }

        // Check the array dimensionality
        if (declaration1.isArray()) {
            return declaration1.getDimensionality() == declaration2.getDimensionality();
        }

        return isAssignableTo(declaration1.getType(), declaration2.getType());
    }

    @Override
    public boolean isTypeResolvable(Object type) {
        return ((IType) type).isResolvable();
    }

    @Override
    public void newSubqueryContext(SimpleSelectStatement expression) {
        queryContext.newSubqueryContext(expression);
    }

    @Override
    public IMapping resolveMapping(Expression expression) {
        return queryContext.getResolver(expression).getMapping();
    }

    @Override
    public IMapping resolveMapping(String variableName, String name) {

        Resolver parent = queryContext.getResolver(variableName);
        Resolver resolver = parent.getChild(name);

        if (resolver == null) {
            resolver = new StateFieldResolver(parent, name);
            parent.addChild(variableName, resolver);
        }

        return resolver.getMapping();
    }

    protected static class IdentificationVariableVisitor extends AbstractExpressionVisitor {

        /**
         *
         */
        protected IdentificationVariable identificationVariable;

        @Override
        public void visit(IdentificationVariable expression) {
            identificationVariable = expression;
        }
    }
}
