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

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

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.apt.core.env.Phase;
import org.eclipse.jdt.apt.core.internal.AptPlugin;
import org.eclipse.jdt.apt.core.internal.declaration.EclipseMirrorObject;
import org.eclipse.jdt.apt.core.internal.declaration.TypeDeclarationImpl;
import org.eclipse.jdt.apt.core.internal.env.MessagerImpl.Severity;
import org.eclipse.jdt.apt.core.internal.util.Factory;
import org.eclipse.jdt.apt.core.internal.util.Visitors.AnnotatedNodeVisitor;
import org.eclipse.jdt.apt.core.internal.util.Visitors.AnnotationVisitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.BuildContext;
import org.eclipse.jdt.core.dom.*;
import com.sun.mirror.apt.Filer;
import com.sun.mirror.declaration.AnnotationTypeDeclaration;
import com.sun.mirror.declaration.PackageDeclaration;
import com.sun.mirror.declaration.TypeDeclaration;

public class BuildEnv extends AbstractCompilationEnv
{	
	private boolean _hasRaisedErrors = false;

	private final BuildFilerImpl _filer;	

	/**
	 * Set of strings that indicate new type dependencies introduced on the file
	 * each string is a fully-qualified type name.
	 */
	private Set<String> _typeDependencies = new HashSet<String>();
	
	/**
	 * Indicates whether we are in batch mode or not. This gets flipped only 
	 * during build and could be flipped back and forth. 
	 */
	private boolean _batchMode = false; // off by default.

	/** 
	 * Holds all the files that contains annotation that are to be processed during build.
	 * If we are not in batch mode, <code>super._file</code> holds the file 
	 * being processed at the time. 
	 */ 
	private BuildContext[] _filesWithAnnotation = null;
	
	/**
	 * These are files that are part of a build but does not have annotations on it.
	 * During batch mode processing, these files still also need to be included. 
	 */
	private BuildContext[] _additionFiles = null;
	/** 
	 * This is intialized when <code>_batchMode</code> is set to be <code>true</code> or
	 * when batch processing is expected. <p>
	 * It is also set in build mode for perf reason rather than parsing and resolving
	 * each file individually.
	 * @see #getAllAnnotationTypes(Map)
	 */
	private CompilationUnit[] _astRoots = null;
	private List<MarkerInfo> _markerInfos = null;
    
    /**
     * Constructor for creating a processor environment used during build.
     * @param filesWithAnnotations
     * @param additionalFiles
     * @param units
     * @param javaProj
     * @param phase
     */
    BuildEnv(
			final BuildContext[] filesWithAnnotations,
			final BuildContext[] additionalFiles,
			final IJavaProject javaProj) {
    	
    	super(null, null, javaProj, Phase.BUILD);
		_filer = new BuildFilerImpl(this);
		_filesWithAnnotation = filesWithAnnotations;
		_additionFiles = additionalFiles;
		_problems = new ArrayList<APTProblem>();
		_markerInfos = new ArrayList<MarkerInfo>();
		
		if (AptPlugin.DEBUG_COMPILATION_ENV) AptPlugin.trace( 
				"constructed " + this + " for " + _filesWithAnnotation.length + " files"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	}

    public Filer getFiler()
    {
		checkValid();
        return _filer;
    }
    public PackageDeclaration getPackage(String name)
    {
		checkValid();
		return super.getPackage(name);
    }

    public TypeDeclaration getTypeDeclaration(String name)
    {
		checkValid();		
		TypeDeclaration decl = super.getTypeDeclaration(name);
		
		if (!_batchMode) 
			addTypeDependency(name);
			
		return decl;
    }

	/**
	 * @return true iff errors (MessagerImpl.Severity.Error) has been posted
	 *         Always return false when this environment is closed.
	 */
	public boolean hasRaisedErrors(){
		return _hasRaisedErrors;
	}	

	public static InputStreamReader getFileReader( final IFile file ) throws IOException, CoreException {
		return new InputStreamReader(getInputStream(file), file.getCharset());
	}

	public static InputStream getInputStream( final IFile file ) throws IOException, CoreException {
		return new BufferedInputStream(file.getContents());
	}

	/**
	 * @return true iff class files has been generated.
	 *         Always return false when this environment is closed.
	 */
	public boolean hasGeneratedClassFiles(){ return _filer.hasGeneratedClassFile(); }

	/* (non-Javadoc)
	 *  Once the environment is closed the following is not allowed
	 *  1) posting messge
	 *  2) generating file
	 *  3) retrieving type or package by name
	 *  4) add or remove listeners
	 */
    public void close(){
    	if( isClosed() ) 
    		return;
    	_markerInfos = null;
    	_astRoot = null;
    	_file = null;
    	_astRoots = null;
    	_filesWithAnnotation = null;
    	_problems = null;
        _modelCompUnit2astCompUnit.clear();		
		_hasRaisedErrors = false;
		super.close();
    }
    
    /**
     * 
     * @param resource null to indicate current resource
     * @param start the starting offset of the marker
     * @param end -1 to indicate unknow ending offset.
     * @param severity the severity of the marker
     * @param msg the message on the marker
     * @param line the line number of where the marker should be
     */
    void addMessage(IFile resource, 
       		        int start, 
    				int end,
                    Severity severity, 
                    String msg, 
                    int line,
                    String[] arguments)
    {
    	checkValid();
    	
    	if( resource == null )
    		resource = getFile();
    	
    	_hasRaisedErrors |= severity == MessagerImpl.Severity.ERROR;
    	
    	// Eclipse doesn't support INFO-level IProblems, so we send them to the log instead.
    	if ( severity == Severity.INFO) {
    		StringBuilder sb = new StringBuilder();
    		sb.append("Informational message reported by annotation processor:\n"); //$NON-NLS-1$
    		sb.append(msg);
    		sb.append("\n"); //$NON-NLS-1$
    		if (resource != null) {
    			sb.append("Resource="); //$NON-NLS-1$
    			sb.append(resource.getName());
    			sb.append("; "); //$NON-NLS-1$
    		}
    		sb.append("starting offset="); //$NON-NLS-1$
    		sb.append(start);
    		sb.append("; ending offset="); //$NON-NLS-1$
    		sb.append(end);
    		sb.append("; line="); //$NON-NLS-1$
    		sb.append(line);
    		if (arguments != null) {
    			sb.append("; arguments:"); //$NON-NLS-1$
    			for (String s : arguments) {
    				sb.append("\n"); //$NON-NLS-1$
    				sb.append(s);
    			}
    		}
    		else {
    			sb.append("\n"); //$NON-NLS-1$
    		}
    		IStatus status = AptPlugin.createInfoStatus(null, sb.toString());
    		AptPlugin.log(status);
    		return;
    	}
    	
    	if( resource == null ){
    		assert _batchMode : "not in batch mode but don't know about current resource"; //$NON-NLS-1$
    		addMarker(start, end, severity, msg, line, arguments);
    	}
    	else    	
    		addProblem(resource, start, end, severity, msg, line, arguments);
    }
    
    private void addProblem(
    		IFile resource, 
		    int start, 
			int end,
            Severity severity, 
            String msg, 
            int line,
            String[] arguments)
    {	 
    	 	
    	APTProblem problem = createProblem(resource, start, end, severity, msg, line, arguments);
    	_problems.add(problem);
    }
    
    private void addMarker(
    		int start, 
			int end,
            Severity severity, 
            String msg, 
            int line,
            String[] arguments)
    {    	
    	
    	// Note that the arguments are ignored -- no quick-fix for markers.
    	_markerInfos.add(new MarkerInfo(start, end, severity, msg, line));
    }
    
    public Map<String, AnnotationTypeDeclaration> getAnnotationTypes()
    {
    	checkValid();
    	assert _astRoot != null && _file != null && !_batchMode : 
    		"operation not available under batch mode."; //$NON-NLS-1$
    	return super.getAnnotationTypes();
    }
    
    /**
	 * Return all annotations at declaration level within all compilation unit(s)
	 * associated with this environment. All the files associated with this environment will 
	 * be parsed and resolved for all declaration level elements at the return of this call.
	 * 
	 * @param file2Annotations populated by this method to map files to the annotation types
	 *        if contains. May be null.
	 * @return the map containing all annotation types found within this environment.
	 */
    public Map<String, AnnotationTypeDeclaration> getAllAnnotationTypes(
    		final Map<BuildContext, Set<AnnotationTypeDeclaration>> file2Annotations) {
    	
    	checkValid();
    	if( _filesWithAnnotation == null )  
    		return getAnnotationTypes();
    	
		final List<Annotation> instances = new ArrayList<Annotation>();
		final Map<String, AnnotationTypeDeclaration> decls = 
			new HashMap<String, AnnotationTypeDeclaration>();
		final AnnotationVisitor visitor = new AnnotationVisitor(instances);
		for( int astIndex=0, len=_astRoots.length; astIndex<len; astIndex++ ){
			if( _astRoots == null || _astRoots[astIndex] == null  )
				System.err.println();
			_astRoots[astIndex].accept(visitor);
			final Set<AnnotationTypeDeclaration> perFileAnnos = new HashSet<AnnotationTypeDeclaration>(); 
			
			for (int instanceIndex=0, size = instances.size(); instanceIndex < size; instanceIndex++) {
				final Annotation instance = instances.get(instanceIndex);
				final ITypeBinding annoType = instance.resolveTypeBinding();
				if (annoType == null)
					continue;
				final TypeDeclarationImpl decl = 
					Factory.createReferenceType(annoType, this);
				if (decl.kind() == EclipseMirrorObject.MirrorKind.TYPE_ANNOTATION){
					final AnnotationTypeDeclaration annoDecl = (AnnotationTypeDeclaration)decl;
					decls.put(annoDecl.getQualifiedName(), annoDecl);
					perFileAnnos.add(annoDecl);
				}
			}
			if( file2Annotations != null && !perFileAnnos.isEmpty() )
				file2Annotations.put(_filesWithAnnotation[astIndex], perFileAnnos);
			visitor.reset();
		}
		
		return decls;
	}

	/**
	 * @return - the extra type dependencies for the files under compilation
	 */
	public Set<String> getTypeDependencies()  { return _typeDependencies; }	
	
	/**
	 * Switch to batch processing mode. 
	 * Note: Call to this method will cause all files associated with this environment to be 
	 * read and parsed.
	 */
	public void beginBatchProcessing(){		
		if( _phase != Phase.BUILD )
			throw new IllegalStateException("No batch processing outside build."); //$NON-NLS-1$
		
		if( _batchMode ) return;
		checkValid();
		
		_batchMode = true;
		_file = null;
		_astRoot = null;
	}
	
	public void completedBatchProcessing(){
		postMarkers();
		completedProcessing();
	}
	
	void createASTs(BuildContext[] cpResults){
		final int len = cpResults.length;
		final ICompilationUnit[] units = new ICompilationUnit[len];
		for( int i=0; i<len; i++ ){
			// may return null if creation failed. this may occur if
			// the file does not exists.
			units[i] = JavaCore.createCompilationUnitFrom(cpResults[i].getFile());
		}
		createASTs(_javaProject, units, _requestor = new CallbackRequestor(units));
	}

	public void beginFileProcessing(BuildContext result){		
		if( result == null )
			throw new IllegalStateException("missing compilation result"); //$NON-NLS-1$
		_batchMode = false;
		final IFile file = result.getFile();
		if( file.equals(_file) ) // this is a no-op
			return;
		
		_astRoot = null;
		_file = null;
		
		// need to match up the file with the ast.
		if( _filesWithAnnotation != null ){
			for( int i=0, len=_filesWithAnnotation.length; i<len; i++ ){
				if( file.equals(_filesWithAnnotation[i].getFile()) ){
					_file = file;
					_astRoot = _astRoots[i];
				}
			}
		}
		
		if( _file == null || _astRoot == null)
			throw new IllegalStateException(
					"file " +  //$NON-NLS-1$
					file.getName() + 
					" is not in the list to be processed."); //$NON-NLS-1$
	}
	
	public void completedFileProcessing(){
		completedProcessing();
	}
	
	@Override
	protected void completedProcessing(){
		_problems.clear();
		_typeDependencies.clear();
		super.completedProcessing();
	}
	
	public List<? extends CategorizedProblem> getProblems(){
		if( !_problems.isEmpty() )
			EnvUtil.updateProblemLength(_problems, getAstCompilationUnit());
		return _problems;
	}
	
	// Implementation for EclipseAnnotationProcessorEnvironment
	public CompilationUnit getAST()
	{
		if( _batchMode ) 
			return null;
		return _astRoot;
	}

	public void addTypeDependency(final String fullyQualifiedTypeName )
	{
		if(!_batchMode){			
			_typeDependencies.add( fullyQualifiedTypeName );
		}
	}
	// End of implementation for EclipseAnnotationProcessorEnvironment
	
	/**
	 * Include all the types from all files, files with and without annotations on it
	 * if we are in batch mode. Otherwise, just the types from the file that's currently
	 * being processed.
	 */
	@SuppressWarnings("unchecked")
	protected List<AbstractTypeDeclaration> searchLocallyForTypeDeclarations()
    {
		if( !_batchMode )
			return super.searchLocallyForTypeDeclarations();
		final List<AbstractTypeDeclaration> typeDecls = new ArrayList<AbstractTypeDeclaration>();
		for( int i=0, len=_astRoots.length; i<len; i++ )
        	typeDecls.addAll( _astRoots[i].types() );
		
		getTypeDeclarationsFromAdditionFiles(typeDecls);
		
		return typeDecls;
    }
	
	@SuppressWarnings("unchecked")
	private void getTypeDeclarationsFromAdditionFiles(List<AbstractTypeDeclaration> typeDecls){
		if( _additionFiles == null || _additionFiles.length == 0 ) return;
	
		final int len = _additionFiles.length;
		final ICompilationUnit[] units = new ICompilationUnit[len];
		for( int i=0; i<len; i++ ){
			// may return null if creation failed. this may occur if
			// the file does not exists.
			units[i] = JavaCore.createCompilationUnitFrom(_additionFiles[i].getFile());
		}
		BaseRequestor r = new BaseRequestor(units);
		createASTs(_javaProject, units, r);
		
		CompilationUnit[] asts = r.asts;
		for( CompilationUnit ast : asts ){
			if( ast != null ){
				typeDecls.addAll( ast.types() );
			}
		}
	}
	
	protected Map<ASTNode, List<Annotation>> getASTNodesWithAnnotations()
    {
		if( !_batchMode )
			return super.getASTNodesWithAnnotations();
    	final Map<ASTNode, List<Annotation>> astNode2Anno = new HashMap<ASTNode, List<Annotation>>();
        final AnnotatedNodeVisitor visitor = new AnnotatedNodeVisitor(astNode2Anno);        
        for( int i=0, len=_astRoots.length; i<len; i++ )
        	_astRoots[i].accept( visitor );
        return astNode2Anno;
    }
	
	protected IFile getFileForNode(final ASTNode node)
	{
		if( !_batchMode )
			return super.getFileForNode(node);
		final CompilationUnit curAST = (CompilationUnit)node.getRoot();
		for( int i=0, len=_astRoots.length; i<len; i++ ){
			if( _astRoots[i] == curAST )
				return _filesWithAnnotation[i].getFile();
		}
		throw new IllegalStateException();
	}
	
	/**
	 * Go through the list of compilation unit in this environment and looking for
	 * the declaration node of the given binding.
	 * @param binding 
	 * @return the compilation unit that defines the given binding or null if no 
	 * match is found.
	 */
	protected CompilationUnit searchLocallyForBinding(final IBinding binding)
	{
		if( !_batchMode )
			return super.searchLocallyForBinding(binding);
		
		for( int i=0, len=_astRoots.length; i<len; i++ ){
			ASTNode node = _astRoots[i].findDeclaringNode(binding);
			if( node != null)
				return _astRoots[i];
		}
		return null;
	}
	
	/**
	 * Go through the list of compilation unit in this environment and looking for
	 * the declaration node of the given binding.
	 * @param binding 
	 * @return the compilation unit that defines the given binding or null if no 
	 * match is found.
	 */
	protected IFile searchLocallyForIFile(final IBinding binding)
	{
		if( !_batchMode )
			return super.searchLocallyForIFile(binding);
		
		for( int i=0, len=_astRoots.length; i<len; i++ ){
			ASTNode node = _astRoots[i].findDeclaringNode(binding);
			if( node != null)
				return _filesWithAnnotation[i].getFile();
		}
		return null;
	}
	
	/**
     * @param file
     * @return the compilation unit associated with the given file.
     * If the file is not one of those that this environment is currently processing,
     * return null;
     */
	public CompilationUnit getASTFrom(final IFile file)
	{
		if( file == null ) 
    		return null;
    	else if( file.equals(_file) )
    		return _astRoot;
    	else if( _astRoots != null ){
    		for( int i=0, len=_filesWithAnnotation.length; i<len; i++ ){
        		if( file.equals(_filesWithAnnotation[i].getFile()) )
        			return _astRoots[i];
        	}
    	}
    	return null;
	}
	
	/**
	 * @return the current ast being processed if in per-file mode.
	 * If in batch mode, one of the asts being processed (no guarantee which
	 * one will be returned.  
	 */
	protected AST getCurrentDietAST(){
		
		if( _astRoot != null )
			return _astRoot.getAST();
		else{
			if( _astRoots == null )
				throw new IllegalStateException("no AST is available"); //$NON-NLS-1$
			return _astRoots[0].getAST();
		}
	}
	
	void postMarkers()
    {
		if( _markerInfos == null || _markerInfos.size() == 0 )
			return;
		// Posting all the markers to the workspace. Doing this in a batch process
		// to minimize the amount of notification.
		try{
	        final IWorkspaceRunnable runnable = new IWorkspaceRunnable(){
	            public void run(IProgressMonitor monitor)
	            {		
	                for( MarkerInfo markerInfo : _markerInfos ){	                  
						try{
		                    final IMarker marker = _javaProject.getProject().createMarker(AptPlugin.APT_BATCH_PROCESSOR_PROBLEM_MARKER);
		                    markerInfo.copyIntoMarker(marker);
						}
						catch(CoreException e){
							AptPlugin.log(e, "Failure posting markers"); //$NON-NLS-1$
						}
	                }
	            }
	        };
	        IWorkspace ws = _javaProject.getProject().getWorkspace();
			ws.run(runnable, null);
		}
		catch(CoreException e){
			AptPlugin.log(e, "Failed to post markers"); //$NON-NLS-1$
		}
		finally{
			_markerInfos.clear();
		}
    }
	
	public BuildContext[] getFilesWithAnnotation()
	{
		return _filesWithAnnotation;
	}
	
	public BuildContext[] getFilesWithoutAnnotation()
	{
		return _additionFiles;
	}
	
	private class CallbackRequestor extends BaseRequestor {
		CallbackRequestor(ICompilationUnit[] parseUnits) {
			super(parseUnits);
		}
		public void acceptBinding(String bindingKey, IBinding binding) {
			// If we have recieved the last ast we have requested,
			// then assign the asts, then begin dispatch
			_astRoots = asts;
			_callback.run(BuildEnv.this);
		}		
	}
	
}
