/*
 * Copyright (c) 1998, 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 from Oracle TopLink
package org.eclipse.persistence.internal.jpa.parsing;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.JPQLException;

/**
 * INTERNAL
 * <p><b>Purpose</b>: The ParseTreeContext holds and manages context information for the parse tree for validation.
 * <p><b>Responsibilities</b>:<ul>
 * <li> Associate schema names with variables
 * <li> Associate identifier with nodes
 * <li> Answer an alias for a variable name
 * <li> Answer a class for a variable name
 * <li> Answer a class loader
 * <li> Answer true if there is a class for a variable name
 * <li> Answer a node for a given identifier
 * <li> Print the context on a string
 * </ul>
 * @see ParseTree
 *    @author Jon Driscoll and Joel Lucuik
 *    @since TopLink 4.0
 */
public class ParseTreeContext {
    private Map<String, VariableDecl> variableDecls;
    private String baseVariable;
    private int currentScope;
    private Set<String> outerScopeVariables;
    private Map<String, List<Node>> fetchJoins;
    private TypeHelper typeHelper;
    private Map<String, Object> parameterTypes;
    private List<String> parameterNames;
    private NodeFactory nodeFactory;
    private String queryInfo;

    /**
     * INTERNAL
     * Return a new initialized ParseTreeContext
     */
    public ParseTreeContext(NodeFactory nodeFactory, String queryInfo) {
        super();
        variableDecls = new HashMap<>();
        currentScope = 0;
        fetchJoins = new HashMap<>();
        typeHelper = null;
        parameterTypes = new HashMap<>();
        parameterNames = new ArrayList<>();
        this.nodeFactory = nodeFactory;
        this.queryInfo = queryInfo;
    }

    /**
     * INTERNAL
     * Associate the given schema with the given variable.
     */
    public void registerSchema(String variable, String schema, int line, int column) {
        VariableDecl decl = variableDecls.get(variable);
        if (decl == null) {
            decl = new VariableDecl(variable, schema);
            variableDecls.put(variable, decl);
        } else {
            String text = decl.isRangeVariable ? decl.schema : decl.path.getAsString();
            throw JPQLException.multipleVariableDeclaration(
                getQueryInfo(), line, column, variable, text);
        }
    }

    /**
     * INTERNAL
     * Associate the given path with the given variable.
     */
    public void registerJoinVariable(String variable, Node path, int line, int column) {
        VariableDecl decl = variableDecls.get(variable);
        if (decl == null) {
            decl = new VariableDecl(variable, path);
            variableDecls.put(variable, decl);
        } else {
            String text = decl.isRangeVariable ? decl.schema : decl.path.getAsString();
            throw JPQLException.multipleVariableDeclaration(
                getQueryInfo(), line, column, variable, text);
        }
    }
    /**
     * INTERNAL
     */
    public void unregisterVariable(String variable) {
        variableDecls.remove(variable);
    }

    /**
     * INTERNAL
     * Returns true if the specified string denotes a variable.
     */
    public boolean isVariable(String variable) {
        VariableDecl decl = variableDecls.get(variable);
        return decl != null;
    }

    /**
     * INTERNAL
     * Returns true if the specified string denotes a range variable.
     */
    public boolean isRangeVariable(String variable) {
        VariableDecl decl = variableDecls.get(variable);
        return (decl != null) && decl.isRangeVariable;
    }

    /**
     * INTERNAL
     * Returns the abstract schema name if the specified string denotes a
     * range variable.
     */
    public String schemaForVariable(String variable) {
        VariableDecl decl = variableDecls.get(variable);
        return (decl != null) ? decl.schema : null;
    }

    /**
     * INTERNAL
     * Answer the class associated with the provided schema name
     */
    public Class<?> classForSchemaName(String schemaName, GenerationContext context) {
        ClassDescriptor descriptor = context.getSession().getDescriptorForAlias(schemaName);
        if (descriptor == null) {
            throw JPQLException.entityTypeNotFound(getQueryInfo(), schemaName);
        }
        Class<?> theClass = descriptor.getJavaClass();
        if (theClass == null) {
            throw JPQLException.resolutionClassNotFoundException(getQueryInfo(), schemaName);
        }
        return theClass;
    }

    /**
     * INTERNAL
     * getVariableNameForClass():
     *        Answer the name mapped to the specified class. Answer null if none found.
     * SELECT OBJECT (emp) FROM Employee emp
     *   getVariableNameForClass(Employee.class) =&gt; "emp"
     */
    public String getVariableNameForClass(Class<?> theClass, GenerationContext context) {
        for (Iterator<Map.Entry<String, VariableDecl>> i = variableDecls.entrySet().iterator(); i.hasNext(); ) {
            Map.Entry<String, VariableDecl> entry = i.next();
            String nextVariable = entry.getKey();
            VariableDecl decl = entry.getValue();
            if ((decl.schema != null) &&
                (theClass == this.classForSchemaName(decl.schema, context))) {
                return nextVariable;
            }
        }
        return null;
    }

    /**
     * INTERNAL
     * Returns the path if the specified string denotes a join or collection
     * member variable.
     */
    public Node pathForVariable(String variable) {
        VariableDecl decl = variableDecls.get(variable);
        return (decl != null) ? decl.path : null;
    }

    /** */
    public String getBaseVariable() {
        return baseVariable;
    }

    /** */
    public void setBaseVariable(String variable) {
        this.baseVariable = variable;
    }

    /** */
    public NodeFactory getNodeFactory() {
        return nodeFactory;
    }

    /** */
    public String getQueryInfo() {
        return queryInfo;
    }

    /**
     * INTERNAL
     * Returns true if the specified string denotes a variable declared in an
     * outer scope.
     */
    public boolean isDeclaredInOuterScope(String variable) {
        VariableDecl decl = variableDecls.get(variable);
        return decl != null && (decl.scope < currentScope);
    }

    /**
     * INTERNAL
     * Sets the scope of the specified variable to the current scope.
     */
    public void setScopeOfVariable(String variable) {
        VariableDecl decl = variableDecls.get(variable);
        if (decl != null) {
            decl.scope = currentScope;
        }
    }

    /**
     * INTERNAL
     * Enters a new scope. This initializes the set of outer scope variables.
     */
    public void enterScope() {
        currentScope++;
        resetOuterScopeVariables();
    }

    /**
     * INTERNAL
     * Leaves the current scope.
     */
    public void leaveScope() {
        currentScope--;
    }

    /**
     * INTERNAL
     * Adds the specified variable to the set of outer scope variables.
     */
    public void registerOuterScopeVariable(String variable) {
        outerScopeVariables.add(variable);
    }

    /**
     * INTERNAL
     * Returns the set of outer scope variables.
     */
    public Set<String> getOuterScopeVariables() {
        return outerScopeVariables;
    }

    /**
     * INTERNAL
     * Resets the set of outer scope variables.
     */
    public void resetOuterScopeVariables() {
        outerScopeVariables = new HashSet<>();
    }

    /**
     * INTERNAL
     * Resets the set of outer scope variables.
     */
    public void resetOuterScopeVariables(Set<String> variables) {
        outerScopeVariables = variables;
    }

    /**
     * Associate the given variableName with the given node representing a
     * JOIN FETCH node.
     */
    public void registerFetchJoin(String variableName, Node node) {
        List<Node> joins = fetchJoins.get(variableName);
        if (joins == null) {
            joins = new ArrayList<>();
            fetchJoins.put(variableName, joins);
        }
        joins.add(node);
    }

    /** Returns a list of FETCH JOIN nodes for the specified attached to the
     * specified variable.
     */
    public List<Node> getFetchJoins(String variableName) {
        return fetchJoins.get(variableName);
    }

    /** Mark the specified variable as used if it is declared in the current
     * scope. */
    public void usedVariable(String variable) {
        VariableDecl decl = variableDecls.get(variable);
        if ((decl != null) && (decl.scope == currentScope)) {
            decl.used = true;
        }
    }

    /** Returns s set of variables that are declared in the current scope,
     * but not used in the query.
     */
    public Set<String> getUnusedVariables() {
        Set<String> unused = new HashSet<>();
        for (Iterator<Map.Entry<String, VariableDecl>> i = variableDecls.entrySet().iterator(); i.hasNext();) {
            Map.Entry<String, VariableDecl> entry = i.next();
            String variable = entry.getKey();
            VariableDecl decl = entry.getValue();
            if ((decl.scope == currentScope) && !decl.used) {
                unused.add(variable);
            }
        }
        return unused;
    }

    //answer true if two or more variables are mapped to the same type name in variableTypes
    //true => "SELECT OBJECT (emp1) FROM Employee emp1, Employee emp2 WHERE ..."
    //false => "SELECT OBJECT (emp) FROM Employee emp WHERE ..."
    public boolean hasMoreThanOneVariablePerType() {
        Map<String, String> typeNamesToVariables = new HashMap<>();
        int nrOfRangeVariables = 0;
        //Map the Aliases to the variable names, then check the count
        for (Iterator<Map.Entry<String, VariableDecl>> i = variableDecls.entrySet().iterator(); i.hasNext(); ) {
            Map.Entry<String, VariableDecl> entry = i.next();
            String variable = entry.getKey();
            VariableDecl decl = entry.getValue();
            if (decl.isRangeVariable) {
                nrOfRangeVariables++;
                typeNamesToVariables.put(decl.schema, variable);
            }
        }
        return typeNamesToVariables.size() != nrOfRangeVariables;
    }

    //answer true if two or more aliases are involved in the FROM (different types)
    //true => "SELECT OBJECT (emp1) FROM Employee emp1, Address addr1 WHERE ..."
    //false => "SELECT OBJECT (emp) FROM Employee emp WHERE ..."
    //false => "SELECT OBJECT (emp1) FROM Employee emp1, Employee emp2 WHERE ..."
    public boolean hasMoreThanOneAliasInFrom() {
        Map<String, String> typeNamesToVariables = new HashMap<>();
        for (Iterator<Map.Entry<String, VariableDecl>> i = variableDecls.entrySet().iterator(); i.hasNext(); ) {
            Map.Entry<String, VariableDecl> entry = i.next();
            String variable = entry.getKey();
            VariableDecl decl = entry.getValue();
            if (decl.isRangeVariable) {
                typeNamesToVariables.put(decl.schema, variable);
            }
        }
        return typeNamesToVariables.size() > 1;
    }

    /**
     * INTERNAL
     * Returns the type helper stored in this context.
     */
    public TypeHelper getTypeHelper() {
        return typeHelper;
    }

    /**
     * INTERNAL
     * Stores the specified type helper in this context.
     */
    public void setTypeHelper(TypeHelper typeHelper) {
        this.typeHelper = typeHelper;
    }

    /**
     * INTERNAL
     * Add a parameter.
     */
    public void addParameter(String parameterName) {
        if (!parameterNames.contains(parameterName)){
            parameterNames.add(parameterName);
        }
    }

    /**
     * INTERNAL
     * Defines the type of the parameter with the specified name.
     */
    public void defineParameterType(String parameterName, Object parameterType,
        int line, int column) {
        if (parameterTypes.containsKey(parameterName)) {
            // existing entry
            Object oldType = parameterTypes.get(parameterName);
            if (typeHelper.isAssignableFrom(oldType, parameterType)) {
                // OK
            } else if (typeHelper.isAssignableFrom(parameterType, oldType)) {
                // new parameter type is more general
                parameterTypes.put(parameterName, parameterType);
            } else {
                // error case old usage and new usage do not match type
                throw JPQLException.invalidMultipleUseOfSameParameter(
                    getQueryInfo(), line, column, parameterName,
                    typeHelper.getTypeName(oldType),
                    typeHelper.getTypeName(parameterType));
            }
        } else {
            // new entry
            parameterTypes.put(parameterName, parameterType);
        }
    }

    /**
     * INTERNAL
     * Returns true if the query has at least one parameter.
     */
    public boolean hasParameters() {
        return !parameterNames.isEmpty();
    }

    /**
     * INTERNAL
     * Return the type of the specified parameter.
     */
    public Object getParameterType(String parameter) {
        return parameterTypes.get(parameter);
    }

    /**
     * INTERNAL
     * Return the parameter names.
     */
    public List<String> getParameterNames() {
        return parameterNames;
    }

    /**
     * INTERNAL
     * Class defining the type of the values the variableDecls map.
     * It holds the following values:
     * variable - the name of the variable
     * isRangeVariable - true if the variable is declared as range variable
     * schema - the abstract for a range variable
     * path - the path for join or collection member variable
     * scope - the scope of the variable
     * used - true if the variable is used in any of the clauses
     */
    static class VariableDecl {
        public final String variable;
        public final boolean isRangeVariable;
        public final String schema;
        public final Node path;
        public int scope;
        public boolean used;
        public VariableDecl(String variable, String schema) {
            this.variable = variable;
            this.isRangeVariable = true;
            this.schema = schema;
            this.path = null;
            this.used = false;
        }
        public VariableDecl(String variable, Node path) {
            this.variable = variable;
            this.isRangeVariable = false;
            this.schema = null;
            this.path = path;
            this.used = false;
        }
    }
}
