/*******************************************************************************
 * Copyright (c) 2001, 2009 Oracle Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.common.internal.types;

import java.util.ArrayList;
import java.util.Collection;
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.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IElementChangedListener;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.ITypeRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
import org.eclipse.jst.jsf.context.symbol.IBeanMethodSymbol;
import org.eclipse.jst.jsf.context.symbol.IBeanPropertySymbol;

/**Provides a cache for java IType properties. It can cache bean property symbols, method symbols,
 * supertypes and implemented interfaces per IType. The cache listens to changes in the java model
 * and invalidates affected properties, but does not update them.
 * 
 * @author Matthias
 */
public class TypeInfoCache implements IElementChangedListener {
    
    private static TypeInfoCache instance = null;
    
    /**Returns the TypeInfoCache instance.  This instance is considered
     * protected and must not be disposded with disposeInstance.
     * 
     * @return the TypeInfoCache instance
     */
    public static synchronized TypeInfoCache getInstance() {
        if (instance == null) {
            instance = createNewInstance();
        }
        return instance;
    }
    
    /**
     * Create a new instance of the type cache.
     * 
     * @return a new instance of the type info cache.
     */
    public static TypeInfoCache createNewInstance()
    {
        final TypeInfoCache newCache = new TypeInfoCache();
        JavaCore.addElementChangedListener(newCache, ElementChangedEvent.POST_CHANGE);
        return newCache;
    }
    
    /**
     * If cache is not the singleton instance acquired with {@link #getInstance()}
     * then the cache will be disposed and should not be used.  If cache is
     * protected instance, then nothing will happen (the singleton instance
     * cannot be disposed).
     * 
     * @param cache
     */
    public static void disposeInstance(final TypeInfoCache cache)
    {
        if (cache != null 
                && cache != instance)        
        {
            JavaCore.removeElementChangedListener(cache);
            
            synchronized(cache)
            {
                if (cache.cachedInfo != null)
                {
                    cache.cachedInfo.clear();
                }
                
                if (cache.cachedTypesByAffectingTypeRoot != null)
                {
                    cache.cachedTypesByAffectingTypeRoot.clear();
                }
                
                if (cache.cachedTypesByMissingSupertypename != null)
                {
                    cache.cachedTypesByMissingSupertypename.clear();
                }
            }
        }
    }
    
    private final Map<IType, TypeInfo> cachedInfo;
    private final Map<ITypeRoot, Set<IType>> cachedTypesByAffectingTypeRoot;
    private final Map<String, Set<IType>> cachedTypesByMissingSupertypename;
    
    private TypeInfoCache() {
        cachedInfo = new HashMap<IType, TypeInfo>();
        cachedTypesByAffectingTypeRoot = new HashMap();
        cachedTypesByMissingSupertypename = new HashMap(10);
    }

    public void elementChanged(ElementChangedEvent event) {
        updateChangedJavaElement(event.getDelta());
    }
    
    /**Returns the cached info({@link TypeInfo}) for a given type. Will
     * return <code>null</code> if no info has been cached or the the type/something it depends on
     * has changed since then.
     * 
     * @param type - the type in question
     * @return a TypeInfo instance that contains all cached info for the given type. May be null.  
     */
    protected TypeInfo getTypeInfo(IType type) {
        TypeInfo info = null;
        if (type != null)
        {
            info = cachedInfo.get(type);
        }
        return info;
    }

    /**Returns the cached bean property symbols for a given type. Will return null if no
     * bean property symbols have been cached or the type/something it depends on has changed since
     * then.
     * @param beanType - the bean type in question
     * @return the bean property symbols for the given type. May be null.
     * @see TypeInfoCache#cachePropertySymbols(IType, IBeanPropertySymbol[])
     */
    public synchronized IBeanPropertySymbol[] getCachedPropertySymbols(IType beanType) {
        IBeanPropertySymbol[] props = null;
        
        if (beanType != null)
        {
            TypeInfo typeInfo = getTypeInfo(beanType);
            if (typeInfo != null)
            {
                props =  typeInfo.getPropertySymbols();
            }
        }
        return props;
    }

    /**Returns the cached method symbols for a given type. Will return null if no
     * method symbols have been cached or the type/something it depends on has changed since
     * then.
     * @param beanType - the bean type in question
     * @return the method symbols for the given type. May be null.
     * @see TypeInfoCache#cacheMethodSymbols(IType, IBeanMethodSymbol[])
     */
    public synchronized IBeanMethodSymbol[] getCachedMethodSymbols(IType beanType) {
        IBeanMethodSymbol[]  methods = null;
        
        if (beanType != null)
        {
            TypeInfo typeInfo = getTypeInfo(beanType);
            if (typeInfo != null)
            {
                methods =  typeInfo.getMethodSymbols();
            }
        }
            
        return methods;
    }
    
    /**Returns the cached supertypes for a given type. Will return null if no supertypes
     * have been cached for this type or if the type/something it depends on has changed since
     * then.
     * @param type - the bean type in question
     * @return the supertypes for the given type. May be null.
     * @see TypeInfoCache#cacheSupertypesFor(IType)
     */
    public synchronized IType[] getCachedSupertypes(IType type) {
        IType[] types = null;
        
        if (type != null)
        {
            TypeInfo typeInfo = getTypeInfo(type);
            if (typeInfo != null)
            {
                types = typeInfo.getSupertypes();
            }
        }
        
        return types;
    }
    
    /**Returns the cached implemented interfaces for a given type. Will return null if no interfaces
     * have been cached for this type or if the type/something it depends on has changed since
     * then.
     * @param type - the bean type in question
     * @return the interface types implemented by the given type. May be null.
     * @see TypeInfoCache#cacheInterfaceTypesFor(IType)
     */
    public synchronized IType[] getCachedInterfaceTypes(IType type) 
    {
        IType[] types = null;
        
        if (type != null)
        {
            TypeInfo typeInfo = getTypeInfo(type);
            if (typeInfo != null)
            {
                types = typeInfo.getInterfaceTypes(); 
            }
        }
        
        return types;
    }
    
    /**Caches the given method symbols for the given type. 
     * @param beanType - the type
     * @param methods - the method symbols to cache
     */
    public synchronized void cacheMethodSymbols(IType beanType, IBeanMethodSymbol[] methods) {
        if (beanType != null)
        {
            TypeInfo typeInfo = getOrCreateTypeInfo(beanType);
            if (typeInfo != null) {
                typeInfo.setMethodSymbols(methods);
            }
        }
    }

    /**Caches the given property symbols for the given type. 
     * @param beanType - the type
     * @param properties - the property symbols to cache
     */
    public synchronized void cachePropertySymbols(IType beanType, IBeanPropertySymbol[] properties) {
        if (beanType != null)
        {
            TypeInfo typeInfo = getOrCreateTypeInfo(beanType);
            if (typeInfo != null) {
                typeInfo.setPropertySymbols(properties);
            }
        }
    }
    
    /**Caches the supertypes for the given type. The supertypes will be calculated (and also returned)
     * by this method.
     * @param type - the type to cache supertypes for
     * @return the supertypes of the given type.
     */
    public synchronized IType[] cacheSupertypesFor(IType type) 
    {
        IType[] types = null;
        
        if (type != null)
        {
            TypeInfo typeInfo = getOrCreateTypeInfo(type);
            
            if (typeInfo != null)
            {
                types = typeInfo.getSupertypes();
            }
        }
        return types;
    }

    /**Caches the interface types for the given type. The interface types will be calculated (and also
     * returned) by this method.
     * @param type - the type to cache interface types for
     * @return the interface types implemented by the given type.
     */
    public synchronized IType[] cacheInterfaceTypesFor(IType type) 
    {
        IType[] types = null;
        
        if (type != null)
        {
            TypeInfo typeInfo = getOrCreateTypeInfo(type);
            if (typeInfo != null)
            {
                types = typeInfo.getInterfaceTypes();
            }
        }
        return types;
    }

    /**Returns the TypeInfo for the given type. If no TypeInfo exists for this type, an empty TypeInfo
     * will be created and cached.
     * @param type - the type in question
     * @return the (modifyable) TypeInfo for the given type
     */
    protected TypeInfo getOrCreateTypeInfo(IType type) {
        TypeInfo typeInfo = getTypeInfo(type);
        if (typeInfo == null) {
            try {
                final ITypeHierarchy  hierarchy = 
                    type.newSupertypeHierarchy(new NullProgressMonitor());
                final IType[] supertypes = hierarchy.getAllSuperclasses(type);
                final IType[] interfaceTypes = hierarchy.getAllInterfaces();
                final IType[] rootClasses = hierarchy.getRootClasses();
                List missingSupertypesList = null;
                for (int i = 0; i < rootClasses.length; i++) {
                    String superclassName = rootClasses[i].getSuperclassName();
                    if (superclassName != null) {
                        if (missingSupertypesList == null) {
                            missingSupertypesList = new ArrayList(1);
                        }
                        superclassName = shortTypename(superclassName);
                        missingSupertypesList.add(superclassName);
                    }
                }
                String[] missingSupertypes = null;
                if (missingSupertypesList != null) {
                    missingSupertypes = (String[]) missingSupertypesList.toArray(new String[missingSupertypesList.size()]);
                } else {
                    missingSupertypes = TypeInfo.NO_NAMES;
                }
                typeInfo = new TypeInfo();
                typeInfo.setSupertypes(supertypes);
                typeInfo.setInterfaceTypes(interfaceTypes);
                typeInfo.setMissingSupertypeNames(missingSupertypes);
                cachedInfo.put(type, typeInfo);
                registerCachedType(type, typeInfo);
            } catch (JavaModelException e) {
                JSFCommonPlugin.log(e);
            }
        }
        return typeInfo;
    }

    /**Returns the typename fragment after the last "." (which in most cases is identical to the
     * unqualified typename).
     * Used only to make sure that if n1 and n2 are names of the same type
     * shortname(n1) equals shortname(2) even if one name is qualified and one not.
     * @param typename
     * @return the typename fragment after the last "."
     */
    private String shortTypename(String typename) {
        int pos = typename.lastIndexOf('.');
        if (pos >= 0) {
            typename = typename.substring(pos + 1);
        }
        return typename;
    }
    
    /**
     * Registers the given type for all ITypeRoot's it depends on, so that it can be uncached if
     * one of this ITypeRoot's has changed. The type must be unregistered when it should not be watched
     * anymore.
     * @param type - the type
     * @param typeInfo - TypeInfo of the given type
     * @see TypeInfoCache#unregisterCachedType(IType, TypeInfo)
     */
    protected void registerCachedType(IType type, TypeInfo typeInfo) {
        registerTypeForTypeRoot(type, type.getTypeRoot());
        IType[] supertypes = typeInfo.getSupertypes();
        for (int i = 0; i < supertypes.length; i++) {
            registerTypeForTypeRoot(type, supertypes[i].getTypeRoot());
        }
        String[] missingSupertypeNames = typeInfo.getMissingSupertypeNames();
        if (missingSupertypeNames != null) {
            for (int i = 0; i < missingSupertypeNames.length; i++) {
                registerTypeForMissingSupertype(type, missingSupertypeNames[i]);
            }
        }
    }

    private void registerTypeForTypeRoot(IType type, ITypeRoot typeRoot) {
        Set dependentTypes = cachedTypesByAffectingTypeRoot.get(typeRoot);
        if (dependentTypes == null) {
            dependentTypes = new HashSet(5);
            cachedTypesByAffectingTypeRoot.put(typeRoot, dependentTypes);
        }
        dependentTypes.add(type);
    }

    private void registerTypeForMissingSupertype(IType type, String supertype) {
        Set dependentTypes = cachedTypesByMissingSupertypename.get(supertype);
        if (dependentTypes == null) {
            dependentTypes = new HashSet(5);
            cachedTypesByMissingSupertypename.put(supertype, dependentTypes);
        }
        dependentTypes.add(type);
    }

    /**Unregisters the given type for all ITypeRoot's it depended on.
     * @param type - the type
     * @param typeInfo - TypeInfo of the given type
     */
    protected void unregisterCachedType(IType type, TypeInfo typeInfo) {
        unregisterTypeForTypeRoot(type, type.getTypeRoot());
        IType[] supertypes = typeInfo.getSupertypes();
        for (int i = 0; i < supertypes.length; i++) {
            unregisterTypeForTypeRoot(type, supertypes[i].getTypeRoot());
        }
        String[] missingSupertypeNames = typeInfo.getMissingSupertypeNames();
        if (missingSupertypeNames != null) {
            for (int i = 0; i < missingSupertypeNames.length; i++) {
                unregisterTypeForMissingSupertype(type, missingSupertypeNames[i]);
            }
        }
    }

    private void unregisterTypeForTypeRoot(IType type, ITypeRoot typeRoot) {
        Set dependentTypes = cachedTypesByAffectingTypeRoot.get(typeRoot);
        if (dependentTypes != null) {
            dependentTypes.remove(type);
            if (dependentTypes.isEmpty()) {
                cachedTypesByAffectingTypeRoot.remove(typeRoot);
            }
        }
    }
    
    private void unregisterTypeForMissingSupertype(IType type, String supertype) {
        Set dependentTypes = cachedTypesByMissingSupertypename.get(supertype);
        if (dependentTypes != null) {
            dependentTypes.remove(type);
            if (dependentTypes.isEmpty()) {
                cachedTypesByMissingSupertypename.remove(supertype);
            }
        }
    }
    
    /**This will remove all cached info for all types.
     */
    protected synchronized void uncacheAllTypes() {
        cachedInfo.clear();
        cachedTypesByAffectingTypeRoot.clear();
        cachedTypesByMissingSupertypename.clear();
    }
    
    /**Removes all cached info for all types that are subtypes of a type of the given ITypeRoot. 
     * @param typeRoot
     */
    protected synchronized void uncacheAffectedTypes(ITypeRoot typeRoot) {
        Collection affectedTypes = cachedTypesByAffectingTypeRoot.get(typeRoot);
        if (affectedTypes != null && !affectedTypes.isEmpty()) {
            List affectedTypesCopy = new ArrayList(affectedTypes);
            for (Iterator it = affectedTypesCopy.iterator(); it.hasNext(); ) {
                IType cachedType = (IType) it.next();
                TypeInfo typeInfo = cachedInfo.remove(cachedType);
                unregisterCachedType(cachedType, typeInfo);
            }
        }
    }
    
    /**Removes all cached info for all types (or subtypes of types) that specify a supertype
     * that has a name similar to the given name. 
     * @param supertypename - the missing supertype name. May be qualified or not
     */
    protected synchronized void uncacheTypesWithMissingSupertype(String supertypename) {
        Collection affectedTypes = cachedTypesByMissingSupertypename.get(shortTypename(supertypename));
        if (affectedTypes != null && !affectedTypes.isEmpty()) {
            List affectedTypesCopy = new ArrayList(affectedTypes);
            for (Iterator it = affectedTypesCopy.iterator(); it.hasNext(); ) {
                IType cachedType = (IType) it.next();
                TypeInfo typeInfo = cachedInfo.remove(cachedType);
                unregisterCachedType(cachedType, typeInfo);
            }
        }
    }
    
    /**Removes all cached info that may be affected by the given change.
     * @param delta - the change in the java model
     */
    protected void updateChangedJavaElement(IJavaElementDelta delta) {
        IJavaElement element= delta.getElement();
        switch (element.getElementType()) {
            case IJavaElement.JAVA_MODEL:
                updateChangedJavaModel(delta, element);
                break;
            case IJavaElement.JAVA_PROJECT:
                updateChangedJavaProject(delta, element);
                break;
            case IJavaElement.PACKAGE_FRAGMENT_ROOT:
                updateChangedPackageFragmentRoot(delta, element);
                break;
            case IJavaElement.PACKAGE_FRAGMENT:
                updateChangedPackageFragment(delta, (IPackageFragment) element);
                break;
            case IJavaElement.CLASS_FILE:
            case IJavaElement.COMPILATION_UNIT:
                updateChangedOpenable(delta, element);
                break;
        }
    }
    
    private void updateChangedChildren(IJavaElementDelta delta) {
        if ((delta.getFlags() & IJavaElementDelta.F_CHILDREN) > 0) {
            IJavaElementDelta[] children= delta.getAffectedChildren();
            for (int i= 0; i < children.length; i++) {
                updateChangedJavaElement(children[i]);
            }
        }
    }

    private void updateChangedJavaModel(IJavaElementDelta delta, IJavaElement element) {
        switch (delta.getKind()) {
            case IJavaElementDelta.ADDED :
            case IJavaElementDelta.REMOVED :
                uncacheAllTypes();
                break;
            case IJavaElementDelta.CHANGED :
                updateChangedChildren(delta);
                break;
        }
    }

    private void updateChangedJavaProject(IJavaElementDelta delta, IJavaElement element) {
        int kind = delta.getKind();
        int flags = delta.getFlags();
        if ((flags & IJavaElementDelta.F_OPENED) != 0) {
            kind = IJavaElementDelta.ADDED; // affected in the same way
        }
        if ((flags & IJavaElementDelta.F_CLOSED) != 0) {
            kind = IJavaElementDelta.REMOVED; // affected in the same way
        }
        switch (kind) {
            case IJavaElementDelta.ADDED :
            case IJavaElementDelta.REMOVED :
                uncacheAllTypes();
                break;
            case IJavaElementDelta.CHANGED :
                updateChangedChildren(delta);
                break;
        }
    }

   private void updateChangedPackageFragment(IJavaElementDelta delta, IPackageFragment element) {
        switch (delta.getKind()) {
            case IJavaElementDelta.ADDED :
                // if the package fragment is in the projects being considered, this could
                // introduce new types, changing the hierarchy
            case IJavaElementDelta.REMOVED :
                // is a change if the package fragment contains supertypes?
                uncacheAllTypes();
                break;
            case IJavaElementDelta.CHANGED :
                // look at the files in the package fragment
                updateChangedChildren(delta);
        }
    }

    private void updateChangedPackageFragmentRoot(IJavaElementDelta delta, IJavaElement element) {
        switch (delta.getKind()) {
            case IJavaElementDelta.ADDED :
            case IJavaElementDelta.REMOVED :
                uncacheAllTypes();
                break;
            case IJavaElementDelta.CHANGED :
                int flags = delta.getFlags();
                if (((flags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) > 0)||(flags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) > 0) {
                    uncacheAllTypes();
                } else {
                    updateChangedChildren(delta);
                }
                break;
        }
    }

    /**Removes all cached info that may be affected by the change in this IOpenable
     * @param delta - the change in the java model
     * @param element - the (changed) IOpenable considered
     */
    protected void updateChangedOpenable(IJavaElementDelta delta, IJavaElement element) {
        if (element instanceof ITypeRoot) {
            ITypeRoot typeRoot = (ITypeRoot) element;
            uncacheAffectedTypes(typeRoot);
            // Creates missing superclass for any cached type?
            if (delta.getKind() == IJavaElementDelta.ADDED) {
                if (typeRoot instanceof ICompilationUnit) {
                    ICompilationUnit cu = (ICompilationUnit) typeRoot;
                    try {
                        IType[] types = cu.getAllTypes();
                        for (int i = 0; i < types.length; i++) {
                            uncacheTypesWithMissingSupertype(types[i].getElementName());
                        }
                    } catch (JavaModelException e) {
                        if (!e.isDoesNotExist())
                        {
                            JSFCommonPlugin.log(IStatus.INFO, "Unable to get types for compilation unit " + cu, e); //$NON-NLS-1$
                        }
                        uncacheAllTypes();
                    }
                } else if (typeRoot instanceof IClassFile) {
                    IClassFile cf = (IClassFile) typeRoot;
                    IType type = cf.getType();
                    uncacheTypesWithMissingSupertype(type.getElementName());
                }
            }
        }
    }

}
