/*******************************************************************************
 * Copyright (c) 2010 BSI Business Systems Integration AG.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     BSI Business Systems Integration AG - initial API and implementation
 ******************************************************************************/
package org.eclipse.scout.sdk.util.internal.typecache;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.IRegion;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.scout.commons.CollectionUtility;
import org.eclipse.scout.sdk.util.internal.SdkUtilActivator;
import org.eclipse.scout.sdk.util.jdt.JdtEvent;
import org.eclipse.scout.sdk.util.type.TypeUtility;
import org.eclipse.scout.sdk.util.typecache.ICachedTypeHierarchy;
import org.eclipse.scout.sdk.util.typecache.ICachedTypeHierarchyResult;
import org.eclipse.scout.sdk.util.typecache.IHierarchyCache;
import org.eclipse.scout.sdk.util.typecache.ITypeHierarchy;
import org.eclipse.scout.sdk.util.typecache.TypeHierarchyConstraints;

public final class HierarchyCache implements IHierarchyCache {

  private static final HierarchyCache INSTANCE = new HierarchyCache();

  private final Map<Object, ICacheableTypeHierarchyResult> m_cachedHierarchyResults;

  public static HierarchyCache getInstance() {
    return INSTANCE;
  }

  private HierarchyCache() {
    m_cachedHierarchyResults = new HashMap<Object, ICacheableTypeHierarchyResult>();
  }

  @Override
  public synchronized void dispose() {
    invalidateAll(); // to ensure the resources are released.
    m_cachedHierarchyResults.clear();
  }

  public synchronized List<ICacheableTypeHierarchyResult> getAllCachedHierarchies() {
    return getHierarchiesSafe();
  }

  @Override
  public ICachedTypeHierarchyResult getProjectContextTypeHierarchy(TypeHierarchyConstraints constraints) {
    ICacheableTypeHierarchyResult h = null;
    synchronized (this) {
      h = m_cachedHierarchyResults.get(constraints);
      if (h != null && !TypeUtility.exists(h.getBaseType())) {
        h.invalidate();
        m_cachedHierarchyResults.remove(constraints);
        h = null;
      }
      if (h == null) {
        h = new ProjectContextTypeHierarchyResult(constraints);
        m_cachedHierarchyResults.put(constraints, h);
      }
    }
    return h;
  }

  @Override
  public ICachedTypeHierarchy getTypeHierarchy(IType type) {
    if (!TypeUtility.exists(type) || !type.getJavaProject().exists()) {
      throw new IllegalArgumentException("type does not exist!");
    }
    ICacheableTypeHierarchyResult hierarchy = null;
    synchronized (this) {
      hierarchy = m_cachedHierarchyResults.get(type);
      if (hierarchy != null && (!TypeUtility.exists(hierarchy.getBaseType()) || !TypeUtility.exists(hierarchy.getBaseType().getJavaProject()))) {
        // discard old create new
        hierarchy.invalidate();
        m_cachedHierarchyResults.remove(type);
        hierarchy = null;
      }
      if (hierarchy == null) {
        hierarchy = new CachedTypeHierarchy(type);
        m_cachedHierarchyResults.put(type, hierarchy);
      }
    }
    return (ICachedTypeHierarchy) hierarchy;
  }

  @Override
  public ICachedTypeHierarchy getPrimaryTypeHierarchy(IType type) {
    if (type != null && TypeUtility.exists(type.getDeclaringType())) {
      throw new IllegalArgumentException("type '" + type.getFullyQualifiedName() + "' must be a primary type.");
    }
    return new CachedPrimaryTypeHierarchy(getTypeHierarchy(type));
  }

  synchronized void removeCachedHierarchy(IType type) {
    m_cachedHierarchyResults.remove(type);
  }

  synchronized void replaceCachedHierarchy(Object oldKey, Object newKey, ICacheableTypeHierarchyResult hierarchyToAdd) {
    m_cachedHierarchyResults.remove(oldKey);
    m_cachedHierarchyResults.put(newKey, hierarchyToAdd);
  }

  @Override
  public ITypeHierarchy getLocalTypeHierarchy(IRegion region) {
    try {
      return new TypeHierarchy(null, JavaCore.newTypeHierarchy(region, null, null));
    }
    catch (JavaModelException e) {
      if (!e.isDoesNotExist()) {
        SdkUtilActivator.logWarning("could not build hierarchy of region '" + region + "'.", e);
      }
    }
    return null;
  }

  @Override
  public ITypeHierarchy getSupertypeHierarchy(IType type) {
    if (!TypeUtility.exists(type)) {
      return null;
    }
    try {
      return new TypeHierarchy(type, type.newSupertypeHierarchy(null));
    }
    catch (JavaModelException e) {
      SdkUtilActivator.logWarning("could not build super hierarchy '" + type.getFullyQualifiedName() + "'.", e);
    }
    return null;
  }

  @Override
  public synchronized void invalidateAll() {
    List<ICacheableTypeHierarchyResult> hierarchies = getHierarchiesSafe(); // get a copy to prevent ConcurrentModificationException
    for (ICacheableTypeHierarchyResult h : hierarchies) {
      if (h.isCreated()) {
        h.invalidate();
      }
    }
  }

  private synchronized List<ICacheableTypeHierarchyResult> getHierarchiesSafe() {
    return CollectionUtility.arrayList(m_cachedHierarchyResults.values());
  }

  private void handleTypeChange(IType t, ITypeHierarchy superTypeHierarchy) {
    if (superTypeHierarchy != null) {
      List<ICacheableTypeHierarchyResult> hierarchies = getHierarchiesSafe();
      Set<IType> superTypes = superTypeHierarchy.getAllSupertypes(t);
      for (ICacheableTypeHierarchyResult h : hierarchies) {
        if (h.isCreated() && h.contains(t) != h.isTypeAccepted(t, superTypes)) {
          h.invalidate();
        }
      }
    }
  }

  private void handleTypeRemoved(IType type) {
    List<ICacheableTypeHierarchyResult> hierarchies = getHierarchiesSafe();
    for (ICacheableTypeHierarchyResult h : hierarchies) {
      if (h.isCreated() && h.contains(type)) {
        h.invalidate();
      }
    }
  }

  private void handleJavaElementRemoved(IJavaElement element) {
    if (element.getElementType() < IJavaElement.TYPE) {
      List<ICacheableTypeHierarchyResult> hierarchies = getHierarchiesSafe();
      for (ICacheableTypeHierarchyResult h : hierarchies) {
        if (h.isCreated()) {
          if (TypeUtility.isAncestor(element, h.getBaseType())) {
            h.invalidate();
          }
          else {
            for (IType candidate : h) {
              if (TypeUtility.isAncestor(element, candidate)) {
                h.invalidate();
                break;
              }
            }
          }
        }
      }
    }
    else if (element.getElementType() == IJavaElement.TYPE) {
      handleTypeRemoved((IType) element);
    }
  }

  private void handleCompilationUnitChanged(ICompilationUnit icu) {
    if (!TypeUtility.exists(icu)) {
      return;
    }

    IRegion region = JavaCore.newRegion();
    region.add(icu);
    try {
      ITypeHierarchy hierarchy = getLocalTypeHierarchy(region);
      if (hierarchy != null) {
        for (IType t : icu.getTypes()) {
          reqTypeChangedFromExternal(t, hierarchy);
        }
      }
    }
    catch (JavaModelException e) {
      SdkUtilActivator.logWarning("could not find types in compilation unit '" + icu.getElementName() + "'.", e);
    }
  }

  private void reqTypeChangedFromExternal(IType type, ITypeHierarchy hierarchy) {
    handleTypeChange(type, hierarchy);
    try {
      for (IType subType : type.getTypes()) {
        reqTypeChangedFromExternal(subType, hierarchy);
      }
    }
    catch (JavaModelException e) {
      SdkUtilActivator.logWarning("could not find subtypes of type '" + type.getElementName() + "'.", e);
    }
  }

  /**
   * will be notified before events are passed through the event listener list from {@link JavaResourceChangedEmitter}
   */
  void elementChanged(JdtEvent e) {
    switch (e.getEventType()) {
      case IJavaElementDelta.ADDED:
      case IJavaElementDelta.CHANGED: {
        if (e.getElementType() == IJavaElement.TYPE && e.getDeclaringType() == null) {
          handleTypeChange((IType) e.getElement(), e.getSuperTypeHierarchy());
        }
        else if (e.getElementType() == IJavaElement.COMPILATION_UNIT) {
          handleCompilationUnitChanged((ICompilationUnit) e.getElement());
        }
        else if (e.getElementType() == IJavaElement.JAVA_PROJECT) {
          if ((e.getFlags() & IJavaElementDelta.F_OPENED) != 0 || e.getFlags() == 0) {
            // a new java project has been created/imported/opened/added in the workspace
            invalidateAll();
          }
          else if ((e.getFlags() & IJavaElementDelta.F_CLOSED) != 0) {
            // a project has been closed
            handleJavaElementRemoved(e.getElement());
          }
        }
        else if (e.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT) {
          if ((e.getFlags() & (IJavaElementDelta.F_ADDED_TO_CLASSPATH | IJavaElementDelta.F_REMOVED_FROM_CLASSPATH | IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED | IJavaElementDelta.F_REORDER)) != 0 || e.getFlags() == 0) {
            // the classpath has been changed
            invalidateAll();
          }
        }
        break;
      }
      case IJavaElementDelta.REMOVED: {
        if (TypeUtility.exists(e.getElement().getParent())) {
          handleJavaElementRemoved(e.getElement());
        }
        break;
      }
      case JavaResourceChangedEmitter.CHANGED_EXTERNAL:
        if (e.getElementType() == IJavaElement.COMPILATION_UNIT) {
          handleCompilationUnitChanged((ICompilationUnit) e.getElement());
        }
        else if (e.getElementType() == IJavaElement.TYPE) {
          handleTypeChange((IType) e.getElement(), e.getSuperTypeHierarchy());
        }
        break;
    }
  }
}
