/*******************************************************************************
 * 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.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.apt.core.env.EclipseAnnotationProcessorEnvironment;
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.AnnotationVisitor;
import org.eclipse.jdt.apt.core.util.AptPreferenceConstants;
import org.eclipse.jdt.apt.core.util.EclipseMessager;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.BuildContext;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.ReconcileContext;
import org.eclipse.jdt.core.dom.ASTRequestor;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ITypeBinding;

import com.sun.mirror.apt.AnnotationProcessorFactory;
import com.sun.mirror.apt.AnnotationProcessorListener;
import com.sun.mirror.apt.Filer;
import com.sun.mirror.declaration.AnnotationTypeDeclaration;

/** Base environment to be used during reconcile or build */ 
public abstract class AbstractCompilationEnv 
	extends BaseProcessorEnv 
	implements EclipseAnnotationProcessorEnvironment {
	
	private Set<AnnotationProcessorListener> _listeners = null;
	
	protected List<APTProblem> _problems = new ArrayList<APTProblem>();
	private boolean _isClosed = false;
	
	EnvCallback _callback;

    private Set<IFile> _allGeneratedSourceFiles = new HashSet<IFile>();
    private Set<IFile> _modifiedGeneratedSourceFiles = new HashSet<IFile>();	

    /**
	 * Currently open dom pipeline, used to request type bindings.
	 */
	protected ASTRequestor _requestor;

	/**
	 * The processor that is currently being executed, or null if processing is not underway.
	 */
	private AnnotationProcessorFactory _currentProcessorFactory = null;
	
	public static interface EnvCallback {
		public void run(AbstractCompilationEnv env);
	}
	
	public static void newReconcileEnv(ReconcileContext reconcileContext,  EnvCallback callback)
	{
		assert reconcileContext != null : "reconcile context is null"; //$NON-NLS-1$
		ReconcileEnv env = ReconcileEnv.newEnv(reconcileContext);
		env._callback = callback;
		env.openPipeline();
	}
    
    public static void newBuildEnv(
    		BuildContext[] filesWithAnnotations,
    		final BuildContext[] additionalFiles,
    		IJavaProject javaProj,
    		EnvCallback callback)
    {
    	assert filesWithAnnotations != null : "missing files"; //$NON-NLS-1$    	
    
		// note, we are not reading any files.
		BuildEnv env = new BuildEnv(filesWithAnnotations, additionalFiles, javaProj);
		env._callback = callback;
		env.createASTs(filesWithAnnotations);
    }
	
	AbstractCompilationEnv(
			CompilationUnit compilationUnit,
			IFile file,
			IJavaProject javaProj,
			Phase phase)
	{
		super(compilationUnit, file, javaProj, phase);
	}
	
	@Override
	protected ITypeBinding getTypeBindingFromKey(String key, ICompilationUnit unit) {
		return (ITypeBinding)_requestor.createBindings(new String[] {key})[0];
	}

	public void addListener(AnnotationProcessorListener listener)
    {
		checkValid();
        if(_listeners == null )
			_listeners = new HashSet<AnnotationProcessorListener>();
		_listeners.add(listener);
    }

    public void removeListener(AnnotationProcessorListener listener)
    {
		checkValid();
        if( _listeners == null ) return;
		_listeners.remove(listener);
    }

	public Set<AnnotationProcessorListener> getProcessorListeners()
	{
		if( _listeners == null )
			return Collections.emptySet();
		// Return a copy, to avoid ConcurrentModificationException if a listener
		// removes itself in response to the callback.
		return new HashSet<AnnotationProcessorListener>(_listeners);
	}
	
	public Map<String, String> getOptions()
    {
        final HashMap<String, String> options = new HashMap<String, String>(_options);
		options.put("phase", getPhase().toString()); //$NON-NLS-1$
		return options;
    }
	
	abstract public CompilationUnit getASTFrom(final IFile file);
	
	public CompilationUnit getAST(){
		return _astRoot;
	}
	
	public EclipseMessager getMessager()
    {
		checkValid();
		return new MessagerImpl(this);
	}
	
	abstract void addMessage(
			IFile resource, 
		    int start, 
			int end,
            Severity severity, 
            String msg, 
            int line,
            String[] arguments);
	
	public List<? extends CategorizedProblem> getProblems(){
		checkValid();
		if( !_problems.isEmpty() )
			EnvUtil.updateProblemLength(_problems, getAstCompilationUnit());
		return _problems;
	}
	
	APTProblem createProblem(
	    		IFile resource, 
			    int start, 
				int end,
	            Severity severity, 
	            String msg, 
	            int line,
	            String[] arguments)
    {	 
    	// end-1 since IProblem ending offsets are inclusive but DOM layer
    	// ending offsets are exclusive.
    	final APTProblem newProblem = 
        	new APTProblem(msg, severity, resource, start, end-1, line, arguments);
    	return newProblem;
    }
	
	public abstract Filer getFiler();
	
	public void addGeneratedSourceFile( IFile f, boolean contentsChanged ) {
		if (!f.toString().endsWith(".java")) { //$NON-NLS-1$
			throw new IllegalArgumentException("Source files must be java source files, and end with .java"); //$NON-NLS-1$
		}
		
		boolean addedToAll = _allGeneratedSourceFiles.add(f);
		boolean addedToMod = false;
		if (contentsChanged)
			addedToMod = _modifiedGeneratedSourceFiles.add(f);
		if (AptPlugin.DEBUG_COMPILATION_ENV) {
			AptPlugin.trace("add generated file " + f + " to env " + this + //$NON-NLS-1$ //$NON-NLS-2$
					"; addToAll = " + addedToAll + "; addToMod = " + addedToMod + //$NON-NLS-1$ //$NON-NLS-2$
					"; contentsChanged = " + contentsChanged); //$NON-NLS-1$
		}
	}
	
	public void addGeneratedNonSourceFile(final IFile file) {
		_allGeneratedSourceFiles.add(file);
	}
	
    public Set<IFile> getAllGeneratedFiles() { 
    	return _allGeneratedSourceFiles; 
    }
    
    public Set<IFile> getModifiedGeneratedFiles() { 
    	return _modifiedGeneratedSourceFiles; 
    }

	/**
	 * @return true iff source files has been generated.
	 *         Always return false when this environment is closed.
	 */
	public boolean hasGeneratedSourceFiles(){ return !_allGeneratedSourceFiles.isEmpty();  }


	/**
	 * @return all annotation types in the current compilation unit.
	 */
	public Map<String, AnnotationTypeDeclaration> getAnnotationTypes()
    {
    	checkValid();
    	final List<Annotation> instances = new ArrayList<Annotation>();
		final Map<String, AnnotationTypeDeclaration> decls = 
			new HashMap<String, AnnotationTypeDeclaration>();
		final AnnotationVisitor visitor = new AnnotationVisitor(instances);
		_astRoot.accept(visitor);
			
		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);
			}
		}
		
		return decls;
    }
	
	/* package */ void checkValid()
	{
		if( _isClosed )
			throw new IllegalStateException("Environment has expired"); //$NON-NLS-1$
	}
	
	// Call this after each file; cf. BuildEnv#beginFileProcessing()
	protected void completedProcessing() {
		_modifiedGeneratedSourceFiles.clear();
	}
	
	public void close(){
		if (isClosed()) 
			return; 
		if(_listeners != null)
			_listeners.clear();
		_problems = null;
		_typeCache.clear();
		_packageRootsCache = null;
		_isClosed = true;
		_callback = null;
		_requestor = null;
		_allGeneratedSourceFiles = null;
		_modifiedGeneratedSourceFiles = null;
		if (AptPlugin.DEBUG_COMPILATION_ENV) AptPlugin.trace(
				"closed env " + this); //$NON-NLS-1$
	}
	
	boolean isClosed(){ return _isClosed; }

	/**
	 * Check typeName to ensure it doesn't contain any bogus characters.
	 * @param typeName
	 * @throws CoreException 
	 */
	@SuppressWarnings("unchecked")
	public void validateTypeName(String typeName) throws CoreException
	{
        Map<String, String> options = getJavaProject().getOptions(true);
        String sourceLevel = options.get(JavaCore.COMPILER_SOURCE);
        String complianceLevel = options.get(JavaCore.COMPILER_COMPLIANCE);
        IStatus status = JavaConventions.validateJavaTypeName(typeName, sourceLevel, complianceLevel);
        if (status.matches(IStatus.ERROR)) {
        	throw new CoreException(status);
        }
	}

	public AnnotationProcessorFactory getCurrentProcessorFactory() {
		return _currentProcessorFactory;
	}
	
	public void setCurrentProcessorFactory(AnnotationProcessorFactory processor)
	{
		_currentProcessorFactory = processor;	
	}

	public boolean currentProcessorSupportsRTTG()
	{
		AnnotationProcessorFactory factory = getCurrentProcessorFactory();
		if (null == factory) {
			return false;
		}
		Collection<String> options = factory.supportedOptions();
		if (null == options) {
			return false;
		}
		return options.contains(AptPreferenceConstants.RTTG_ENABLED_OPTION);
	}

}
