 /*******************************************************************************
 * Copyright (c) 2005 BEA Systems, Inc. 
 * 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:
 *    mkaufman@bea.com - initial API and implementation
 *    
 *******************************************************************************/

package org.eclipse.jdt.apt.core.internal;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.apt.core.AptPlugin;
import org.eclipse.jdt.apt.core.internal.generatedfile.GeneratedFileManager;
import org.eclipse.jdt.apt.core.internal.util.FactoryPath;
import org.eclipse.jdt.apt.core.util.AptConfig;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.CompilationParticipant;
import org.eclipse.jdt.core.compiler.ICompilationParticipantResult;
import org.eclipse.jdt.core.compiler.ReconcileContext;

import com.sun.mirror.apt.AnnotationProcessorFactory;

/**
 * A singleton object, created by callback through the
 * org.eclipse.jdt.core.compilationParticipants extension point.
 */
public class AptCompilationParticipant extends CompilationParticipant
{
	/** 
	 * Batch factories that claimed some annotation in a previous round of APT processing.
	 * This currently only apply to the build case since are only generating types during build
	 * and hence cause APT rounding.
	 * The set is an order preserving. The order is determined by their first invocation.
	 */
	private Set<AnnotationProcessorFactory> _previousRoundsBatchFactories = new LinkedHashSet<AnnotationProcessorFactory>();
	private int _buildRound = 0;
	private static AptCompilationParticipant INSTANCE;
	
	public static AptCompilationParticipant getInstance() {
		return INSTANCE;
	}
	
	/**
	 * This class is constructed indirectly, by registering an extension to the 
	 * org.eclipse.jdt.core.compilationParticipants extension point.  Other
	 * clients should NOT construct this object.
	 */
	public AptCompilationParticipant()
	{
		INSTANCE = this;
	}
	
	public boolean isAnnotationProcessor(){
		return true;
	}
	
	public void processAnnotations(ICompilationParticipantResult[] filesWithAnnotations, boolean isBatchBuild) {
		if( filesWithAnnotations == null || filesWithAnnotations.length == 0 )
			return;
		final IProject project = filesWithAnnotations[0].getFile().getProject();
		final IJavaProject javaProject = JavaCore.create(project);
		// Don't dispatch on pre-1.5 project. They cannot legally have annotations
		String javaVersion = javaProject.getOption("org.eclipse.jdt.core.compiler.source", true); //$NON-NLS-1$		
		// Check for 1.3 or 1.4, as we don't want this to break in the future when 1.6
		// is a possibility
		if ("1.3".equals(javaVersion) || "1.4".equals(javaVersion)) { //$NON-NLS-1$ //$NON-NLS-2$
			return;
		}			
		
		try {
			if (isBatchBuild && _buildRound == 0 ) {
				AnnotationProcessorFactoryLoader.getLoader().resetBatchProcessors(javaProject);
				_previousRoundsBatchFactories.clear();
			}
		
			Map<AnnotationProcessorFactory, FactoryPath.Attributes> factories =
				AnnotationProcessorFactoryLoader.getLoader().getFactoriesAndAttributesForProject(javaProject);
			
			AptProject aptProject = AptPlugin.getAptProject(javaProject);
			Set<AnnotationProcessorFactory> dispatchedBatchFactories = 
				APTDispatchRunnable.runAPTDuringBuild(filesWithAnnotations, aptProject, factories, _previousRoundsBatchFactories, isBatchBuild);
			_previousRoundsBatchFactories.addAll(dispatchedBatchFactories);
		}
		finally {
			if (isBatchBuild) {
				// In order to keep from locking jars, we explicitly close any batch-based
				// classloaders we opened
				AnnotationProcessorFactoryLoader.getLoader().closeBatchClassLoader();
			}
			_buildRound ++;
		}
	}
	
	/** 
	 *   Given a Map which maps from a key to a value, where key is an arbitrary 
	 *   type, and where value is a Collection, mergeMaps will ensure that for a key 
	 *   k with value v in source, all of the elements in the Collection v will be 
	 *   moved into the Collection v' corresponding to key k in the destination Map. 
	 * 
	 * @param source - The source map from some key to a Collection.
	 * @param destination - The destination map from some key to a Collection
	 */
	private static void mergeMaps( Map source, Map destination ) {
		if( source == null || destination == null ) return;
		Iterator keys = source.keySet().iterator();
		while( keys.hasNext() ) {
			Object key = keys.next();
			Object val = destination.get( key );
			if ( val != null ) {
				Collection c = (Collection) val;
				c.addAll( (Collection)source.get( key ) );
			}
			else {
				destination.put( key, source.get( key ) );
			}
		}
	}
	
	public void reconcile(ReconcileContext context){
		
		try
		{	
			final ICompilationUnit workingCopy = context.getWorkingCopy();
			if( workingCopy == null ) 
				return;
			IJavaProject javaProject = workingCopy.getJavaProject();			
			if( javaProject == null )
				return;
			AptProject aptProject = AptPlugin.getAptProject(javaProject);
			
			Map<AnnotationProcessorFactory, FactoryPath.Attributes> factories = 
				AnnotationProcessorFactoryLoader.getLoader().getFactoriesAndAttributesForProject( javaProject );
			APTDispatchRunnable.runAPTDuringReconcile(context, aptProject, factories);
		}
		catch ( Throwable t )
		{
			AptPlugin.log(t, "Failure processing");  //$NON-NLS-1$
		}	
	}
	
	public void cleanStarting(IJavaProject javaProject){
		IProject p = javaProject.getProject();
		
		AptPlugin.getAptProject(javaProject).projectClean( true );
		try{
			// clear out all markers during a clean.
			IMarker[] markers = p.findMarkers(AptPlugin.APT_BATCH_PROCESSOR_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
			if( markers != null ){
				for( IMarker marker : markers )
					marker.delete();
			}
		}
		catch(CoreException e){
			AptPlugin.log(e, "Unable to delete batch annotation processor markers"); //$NON-NLS-1$
		}
	}
	
	/**
	 * Does APT have anything to do for this project?
	 * Even if there are no processors on the factory path, apt may still
	 * be involved during a clean.
	 */
	public boolean isActive(IJavaProject project){
		return AptConfig.isEnabled(project);
	}
	
	public int aboutToBuild(IJavaProject project) {
		if (AptConfig.isEnabled(project)) {
			// setup the classpath and make sure the generated source folder is on disk.
		AptPlugin.getAptProject(project).compilationStarted();
		}		
		_buildRound = 0; // reset
		// TODO: (wharley) if the factory path is different we need a full build
		return CompilationParticipant.READY_FOR_BUILD;
	}
    
    private final static String DOT_JAVA = ".java"; //$NON-NLS-1$
}
