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.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.jdt.internal.core.PackageFragment;
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.
     * 
     * @return the TypeInfoCache instance
     */
    public static synchronized TypeInfoCache getInstance() {
        if (instance == null) {
            instance = new TypeInfoCache();
            JavaCore.addElementChangedListener(instance, ElementChangedEvent.POST_CHANGE);
        }
        return instance;
    }
    
    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();
        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 = (TypeInfo) 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 = (Set) 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 = (Set) 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 = (Set) cachedTypesByAffectingTypeRoot.get(typeRoot);
        if (dependentTypes != null) {
            dependentTypes.remove(type);
            if (dependentTypes.isEmpty()) {
                cachedTypesByAffectingTypeRoot.remove(typeRoot);
            }
        }
    }
    
    private void unregisterTypeForMissingSupertype(IType type, String supertype) {
        Set dependentTypes = (Set) 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 = (Collection) 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 = (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 = (Collection) 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 = (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, (PackageFragment) 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, PackageFragment 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) {
                        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());
                }
            }
        }
    }

}
