package org.eclipse.cdt.internal.core.model;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */

import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IArchiveContainer;
import org.eclipse.cdt.core.model.IBinaryContainer;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ICModel;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IParent;
import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.runtime.IPath;

/**
 * This class is used by <code>CModelManager</code> to convert
 * <code>IResourceDelta</code>s into <code>ICElementDelta</code>s.
 * It also does some processing on the <code>CElement</code>s involved
 * (e.g. closing them or updating classpaths).
 */
public class DeltaProcessor {
	
	/**
	 * The <code>CElementDelta</code> corresponding to the <code>IResourceDelta</code> being translated.
	 */
	protected CElementDelta fCurrentDelta;
	
	protected IndexManager indexManager = new IndexManager();
	
	/* The C element that was last created (see createElement(IResource). 
	 * This is used as a stack of C elements (using getParent() to pop it, and 
	 * using the various get*(...) to push it. */
	ICElement currentElement;
	
	static final ICElementDelta[] NO_DELTA = new ICElementDelta[0];

	public static boolean VERBOSE = false;

	// Hold on the element bein renamed.
	ICElement movedFromElement = null;

	/**
	 * Creates the create corresponding to this resource.
	 * Returns null if none was found.
	 */
	protected ICElement createElement(IResource resource) {
		CModelManager manager = CModelManager.getDefault();
		if (resource == null)
			return null;
		ICElement celement = manager.create(resource);
		if (celement == null) {
			ICElement parent = manager.create(resource.getParent());
			// Probably it was deleted, find it
			if (parent instanceof IParent) {
				ICElement[] children;
				if ( CModelManager.getDefault().peekAtInfo(parent) != null ) {
					children = ((CElement)parent).getElementInfo().getChildren();
					for (int i = 0; i < children.length; i++) {
						IResource res = children[i].getResource();
						if (res != null && res.equals(resource)) {
							celement = children[i];
							break;
						}
					}
				}
				// BUG 36424:
				// The Binary may only be visible in the BinaryContainers
				if (celement == null) {
					ICProject cproj = parent.getCProject();
					if (cproj != null) {
						IBinaryContainer bin = cproj.getBinaryContainer();
						children = ((CElement)bin).getElementInfo().getChildren();
						for (int i = 0; i < children.length; i++) {
							IResource res = children[i].getResource();
							if (res != null && res.equals(resource)) {
								celement = children[i];
								break;
							}
						}
					}
				}
				// BUG 36424:
				// The Archive may only be visible in the ArchiveContainers
				if (celement == null) {
					ICProject cproj = parent.getCProject();
					if (cproj != null) {
						IArchiveContainer bin = cproj.getArchiveContainer();
						children = ((CElement)bin).getElementInfo().getChildren();
						for (int i = 0; i < children.length; i++) {
							IResource res = children[i].getResource();
							if (res != null && res.equals(resource)) {
								celement = children[i];
								break;
							}
						}
					}				
				}
			}
		}
		return celement;
	}

	/**
	 * Creates the create corresponding to this resource.
	 * Returns null if none was found.
	 */
	protected ICElement createElement(IPath path) {
		return CModelManager.getDefault().create(path);
	}

	/**
	 * Release the Element from the CModel hastable.
	 * Returns null if none was found.
	 */
	protected void releaseCElement(ICElement celement) {
		CModelManager.getDefault().releaseCElement(celement);
	}

	/**
	 * Adds the given child handle to its parent's cache of children. 
	 */
	protected void addToParentInfo(Openable child) {
		Openable parent = (Openable) child.getParent();
		if (parent != null && parent.isOpen()) {
			CElementInfo info = (CElementInfo)parent.getElementInfo();
			info.addChild(child);
		}
	}

	/**
	 * Processing for an element that has been added:<ul>
	 * <li>If the element is a project, do nothing, and do not process
	 * children, as when a project is created it does not yet have any
	 * natures - specifically a java nature.
	 * <li>If the elemet is not a project, process it as added (see
	 * <code>basicElementAdded</code>.
	 * </ul>
	 */
	protected void elementAdded(ICElement element, IResourceDelta delta) {

		if (element instanceof Openable) {
			addToParentInfo((Openable)element);
		}
		if ((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) {
			//ICElement movedFromElement = createElement(delta.getMovedFromPath());
			if  (movedFromElement == null)
				movedFromElement = createElement(delta.getMovedFromPath());
			fCurrentDelta.movedTo(element, movedFromElement);
			movedFromElement = null;
		} else {
			fCurrentDelta.added(element);
		}
	}

	/**
	 * Processing for the closing of an element - there are two cases:<ul>
	 * <li>when a project is closed (in the platform sense), the
	 * 		CModel reports this as if the CProject has been removed.
	 * <li>otherwise, the CModel reports this
	 *		as a the element being closed (CHANGED + F_CLOSED).
	 * </ul>
	 * <p>In both cases, the children of the element are not processed. When
	 * a resource is closed, the platform reports all children as removed. This
	 * would effectively delete the classpath if we processed children.
	 */
	protected void elementClosed(ICElement element, IResourceDelta delta) {

		if (element.getElementType() == ICElement.C_PROJECT) {
			// treat project closing as removal
			elementRemoved(element, delta);
		} else {
			fCurrentDelta.closed(element);
		}
	}

	/**
	 * Processing for the opening of an element - there are two cases:<ul>
	 * <li>when a project is opened (in the platform sense), the
	 * 		CModel reports this as if the CProject has been added.
	 * <li>otherwise, the CModel reports this
	 *		as a the element being opened (CHANGED + F_CLOSED).
	 * </ul>
	 */
	protected void elementOpened(ICElement element, IResourceDelta delta) {

		if (element.getElementType() == ICElement.C_PROJECT) {
			// treat project opening as addition
			if (hasCNature(delta.getResource())) {
				elementAdded(element, delta);
			}
		} else {
			fCurrentDelta.opened(element);
		}
	}

	/*
	 * Closes the given element, which removes it from the cache of open elements.
	 */
	private void close(Openable element) {
		try {
			element.close();
		} catch (CModelException e) {
			// do nothing
		}
	}

	/**
	 * Generic processing for elements with changed contents:<ul>
	 * <li>The element is closed such that any subsequent accesses will re-open
	 * the element reflecting its new structure.
	 * <li>An entry is made in the delta reporting a content change (K_CHANGE with F_CONTENT flag set).
	 * </ul>
	 */
	protected void elementChanged(ICElement element, IResourceDelta delta) {
		if (element instanceof Openable) {
			close((Openable)element);
		}
		fCurrentDelta.changed(element, ICElementDelta.F_CONTENT);
	}

	/**
	 * Generic processing for a removed element:<ul>
	 * <li>Close the element, removing its structure from the cache
	 * <li>Remove the element from its parent's cache of children
	 * <li>Add a REMOVED entry in the delta
	 * </ul>
	 */
	protected void elementRemoved(ICElement element, IResourceDelta delta) {
		if ((delta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
			IPath movedToPath = delta.getMovedToPath();
			// create the moved to element
			ICElement movedToElement = createElement(movedToPath);
			if (movedToElement == null) {
				// moved outside
				fCurrentDelta.removed(element);
			} else {
				movedFromElement = element;
				fCurrentDelta.movedFrom(element, movedToElement);
			}
		} else {
			fCurrentDelta.removed(element);
		}
		releaseCElement(element);
	}

	/**
	 * Filters the generated <code>CElementDelta</code>s to remove those
	 * which should not be fired (because they don't represent a real change
	 * in the C Model).
	 */
	protected ICElementDelta[] filterRealDeltas(ICElementDelta[] deltas) {

		int length = deltas.length;
		ICElementDelta[] realDeltas = null;
		int index = 0;
		for (int i = 0; i < length; i++) {
			CElementDelta delta = (CElementDelta)deltas[i];
			if (delta == null) {
				continue;
			}
			if (delta.getAffectedChildren().length > 0
				|| delta.getKind() == ICElementDelta.ADDED
				|| delta.getKind() == ICElementDelta.REMOVED
				|| (delta.getFlags() & ICElementDelta.F_CLOSED) != 0
				|| (delta.getFlags() & ICElementDelta.F_OPENED) != 0
				|| delta.resourceDeltasCounter > 0) {

				if (realDeltas == null) {
					realDeltas = new ICElementDelta[length];
				}
				realDeltas[index++] = delta;
			}
		}
		if (index > 0) {
			ICElementDelta[] result = new ICElementDelta[index];
			System.arraycopy(realDeltas, 0, result, 0, index);
			return result;
		} else {
			return NO_DELTA;
		}
	}

	/**
	 * Returns true if the given resource is contained in an open project
	 * with a java nature, otherwise false.
	 */
	protected boolean hasCNature(IResource resource) {
		// ensure the project has a C nature (if open)
		IProject project = resource.getProject();
		if (project.isOpen()) {
			return CoreModel.getDefault().hasCNature(project);
		}
		return false;
	}

	/**
	 * Converts a <code>IResourceDelta</code> rooted in a <code>Workspace</code> into
	 * the corresponding set of <code>ICElementDelta</code>, rooted in the
	 * relevant <code>CModel</code>s.
	 */
	public ICElementDelta[] processResourceDelta(IResourceDelta changes) {

		try {
			ICElement root = (ICModel)CModelManager.getDefault().getCModel();
			
/*
			try {
				changes.accept(new IResourceDeltaVisitor() {
					public boolean visit(IResourceDelta delta) {
						switch (delta.getKind()) {
							case IResourceDelta.ADDED :
							// handle added resource
							System.out.print("ADDED ");
							break;
							case IResourceDelta.REMOVED :
							// handle removed resource
							System.out.print("REMOVED ");
							break;
							case IResourceDelta.CHANGED :
							// handle changed resource
							System.out.print("CHANGED ");
							break;
						}
						System.out.println(delta.getResource());
						return true;
					}
				});
			} catch (CoreException e) {
			}
*/
			// get the workspace delta, and start processing there.
			IResourceDelta[] deltas = changes.getAffectedChildren();
			ICElementDelta[] translatedDeltas = new CElementDelta[deltas.length];
			//System.out.println("delta.length: " + deltas.length);
			for (int i = 0; i < deltas.length; i++) {
				IResourceDelta delta = deltas[i];
				fCurrentDelta = new CElementDelta(root);
				traverseDelta(root, delta); // traverse delta
				translatedDeltas[i] = fCurrentDelta;
			}
			return filterRealDeltas(translatedDeltas);
		} finally {
		}
	}
	
	/**
	 * Converts an <code>IResourceDelta</code> and its children into
	 * the corresponding <code>ICElementDelta</code>s.
	 * Return whether the delta corresponds to a resource on the classpath.
	 * If it is not a resource on the classpath, it will be added as a non-java
	 * resource by the sender of this method.
	 */
	protected void traverseDelta(ICElement parent, IResourceDelta delta) {
		try {
			ICElement current = updateCurrentDeltaAndIndex(delta);
			if (current == null) {
				nonCResourcesChanged(parent, delta);
			} else {
				parent = current;
			}
		} catch (CModelException e) {
		}
		IResourceDelta [] children = delta.getAffectedChildren();
		for (int i = 0; i < children.length; i++) {
				traverseDelta(parent, children[i]);
		}
	}

	protected void nonCResourcesChanged(ICElement parent, IResourceDelta delta) {
		CElementDelta elementDelta = fCurrentDelta.find(parent);
		if (elementDelta == null) {
			fCurrentDelta.changed(parent, ICElementDelta.F_CONTENT);
		} else {
			elementDelta.addResourceDelta(delta);
		}
		if (parent instanceof CContainer) {
			// if info not created yet no need to null NonCResources...
			if (CModelManager.getDefault().peekAtInfo(parent) != null) {
				CElementInfo info = ((CContainer)parent).getElementInfo();
				if (info instanceof CContainerInfo) {
					((CContainerInfo)info).setNonCResources(null);
				}
			}
		}
	}

	/*
	 * Update the current delta (ie. add/remove/change the given element) and update the
	 * correponding index.
	 * Returns whether the children of the given delta must be processed.
	 * @throws a CModelException if the delta doesn't correspond to a c element of the given type.
	 */
	private ICElement updateCurrentDeltaAndIndex(IResourceDelta delta) throws CModelException {

		IResource resource = delta.getResource();
		ICElement element = createElement(resource);

		switch (delta.getKind()) {
			case IResourceDelta.ADDED :
				if (element != null) {
					updateIndexAddResource(element, delta);
					elementAdded(element, delta);
				}
				break;

			case IResourceDelta.REMOVED :
				if (element != null) {
					updateIndexRemoveResource(element, delta);
					elementRemoved(element, delta);
				}
				break;

			case IResourceDelta.CHANGED :
				int flags = delta.getFlags();
				if ((flags & IResourceDelta.CONTENT) != 0) {
					// content has changed
					if (element != null) {
						elementChanged(element, delta);
						updateIndexAddResource(element, delta);
						//check to see if any projects need to be reindexed
						updateDependencies(element);
						
					}
				} else if (resource.getType() == IResource.PROJECT) {
					if ((flags & IResourceDelta.OPEN) != 0) {
						// project has been opened or closed
						IProject res = (IProject)resource;
						if (element != null) {
							if (res.isOpen()) {
								elementOpened(element, delta);
								updateIndexAddResource(element, delta);
							} else {
								elementClosed(element, delta);
								updateIndexRemoveResource(element, delta);
							}
						}
					} else if ((flags & IResourceDelta.DESCRIPTION) != 0) {
						if (element != null) {
							elementAdded(element, delta);
						}
					} else if (element != null) {
						elementChanged(element, delta);
					}
				} else if (element != null) {
					elementChanged(element, delta);
				}
				break;
		}
		return element;
	}

	protected void updateIndexAddResource(ICElement element, IResourceDelta delta) {
	
		if (indexManager == null)
			return;
		
	    switch (element.getElementType()) {
			case ICElement.C_PROJECT :
				this.indexManager.indexAll(element.getCProject().getProject());
				break;
	
			case ICElement.C_UNIT:
				IFile file = (IFile) delta.getResource();
				IProject filesProject = file.getProject();
				indexManager.addSource(file, filesProject.getFullPath());
				break;						
	    }
		
	}

	protected void updateIndexRemoveResource(ICElement element, IResourceDelta delta) {
		
		if (indexManager == null)
						return;

		switch (element.getElementType()) {
			case ICElement.C_PROJECT :
						this.indexManager.removeIndexFamily(element.getCProject().getProject().getFullPath());
						// NB: Discarding index jobs belonging to this project was done during PRE_DELETE
						break;
						// NB: Update of index if project is opened, closed, or its c nature is added or removed
						//     is done in updateCurrentDeltaAndIndex
						
			case ICElement.C_UNIT:
						IFile file = (IFile) delta.getResource();
						indexManager.remove(file.getFullPath().toString(), file.getProject().getProject().getFullPath());
						break;				
		}
	

	}
	
	private void updateDependencies(ICElement element){
	
		IResource resource = element.getResource();
		if (resource == null)
		 return;
		 
		String fileExtension = resource.getFileExtension();
		
		if ((fileExtension != null) &&
			(isValidHeader(fileExtension))){
			indexManager.updateDependencies(resource);
		}
	}	
	
	private boolean isValidHeader(String fileExtension) {
		String[] supportedTypes = CModelManager.headerExtensions;
		for (int i = 0; i < supportedTypes.length; ++i) {
			if (supportedTypes[i].equals(fileExtension))
				return true;
		}
		return false;
	}
}
