/*******************************************************************************
 * 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.tests;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.core.resources.IFolder;
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.core.runtime.IPath;
import org.eclipse.jdt.apt.core.internal.AptPlugin;
import org.eclipse.jdt.apt.core.util.AptConfig;
import org.eclipse.jdt.apt.tests.annotations.BaseProcessor;
import org.eclipse.jdt.apt.tests.annotations.ProcessorTestStatus;
import org.eclipse.jdt.apt.tests.annotations.generic.GenericFactory;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.tests.builder.BuilderTests;
import org.eclipse.jdt.core.tests.builder.Problem;
import org.eclipse.jdt.core.tests.util.Util;

import com.sun.mirror.apt.AnnotationProcessor;

/** 
 * Setup a project for common APT testing.
 */
public abstract class APTTestBase extends BuilderTests{
	
	public APTTestBase(final String name)
	{
		super(name);
	}
	
	/**
	 * Set up a basic project with the following properties.
	 * - java compliances level is 1.5  
	 * - 'src' is the source folder
	 * - 'bin' is the output folder	  
	 * - add java class library into teh build class path
	 * - create and add an annotation jar.
	 */
	public void setUp() throws Exception
	{	
		runFinalizers();
		ProcessorTestStatus.reset();
		
		super.setUp();

		env.resetWorkspace();
		TestUtil.enableAutoBuild(false);

		// project will be deleted by super-class's tearDown() method
		final String projectName = getProjectName();
		if( projectName == null )
			throw new IllegalStateException();
		IJavaProject jproj = createJavaProject(projectName);
		AptConfig.setEnabled(jproj, true);
	}
	
	/**
	 * Create a java project with java libraries and test annotations on classpath
	 * (compiler level is 1.5). Use "src" as source folder and "bin" as output folder.
	 * APT is not enabled.
	 * 
	 * @param projectName
	 * @return a java project that has been added to the current workspace.
	 * @throws Exception
	 */
	protected IJavaProject createJavaProject(final String projectName )
		throws Exception
	{
		IPath projectPath = env.addProject( projectName, "1.5" );
		env.addExternalJars( projectPath, Util.getJavaClassLibs() );
		// remove old package fragment root so that names don't collide
		env.removePackageFragmentRoot( projectPath, "" ); //$NON-NLS-1$
		env.addPackageFragmentRoot( projectPath, "src" ); //$NON-NLS-1$
		env.setOutputFolder( projectPath, "bin" ); //$NON-NLS-1$
		final IJavaProject javaProj = env.getJavaProject( projectPath );
		TestUtil.createAndAddAnnotationJar( javaProj );
		return javaProj;
	}
	
	protected void tearDown()
		throws Exception
	{
		AptPlugin.trace("Tearing down " + getProjectName() );
		runFinalizers();
		GenericFactory.PROCESSOR = null;
		super.tearDown();
	}
	
	private static void runFinalizers() {
        // GC in an attempt to release file lock on Classes.jar
		System.gc();
		System.runFinalization();
		System.gc();
		System.runFinalization();
	}
	
	public String getProjectName()
	{
		return this.getClass().getName() + "Project"; //$NON-NLS-1$
	}

	public IPath getSourcePath()
	{
		IProject project = env.getProject( getProjectName() );
		IFolder srcFolder = project.getFolder( "src" ); //$NON-NLS-1$
		IPath srcRoot = srcFolder.getFullPath();
		return srcRoot;
	}
	
	private String concate(String[] messages){
		final int len = messages == null ? 0 : messages.length;
		StringBuilder buffer = new StringBuilder();
		for(int i=0; i<len; i++ ){
			buffer.append(messages[i]);
			buffer.append('\n');
		}
		return buffer.toString();
	}
	
	private String concate(IMarker[] markers){
		final int len = markers == null ? 0 : markers.length;
		StringBuilder buffer = new StringBuilder();
		for(int i=0; i<len; i++ ){
			try{
				buffer.append(markers[i].getAttribute(IMarker.MESSAGE));
			}
			catch(CoreException ce){
				assertTrue("unexpected core exception" + ce.getMessage(), false); //$NON-NLS-1$
			}
			buffer.append('\n');
		}
		return buffer.toString();
	}
	
	protected void clearProcessorResult(Class<? extends AnnotationProcessor> processor) {
		String propertyName = BaseProcessor.getPropertyName(processor);
		System.clearProperty(propertyName);
	}
	
	/*
	 * Processors can set a result message with BaseProcessor.reportError() or reportSuccess().
	 * This method will cause the test to fail if the processor reported an error.  The result
	 * value will be cleared regardless of success or failure.
	 */
	protected String checkProcessorResult(Class<? extends AnnotationProcessor> processor) {
		String propertyName = BaseProcessor.getPropertyName(processor);
		String result = System.getProperty(propertyName);
		System.clearProperty(propertyName);
		if (!BaseProcessor.SUCCESS.equals(result)) {
			fail(result);
		}
		return result;
	}
	
	/*
	 * Processors can set a result message with BaseProcessor.reportError() or reportSuccess().
	 * This method returns the message reported by the processor, and clears the result value.
	 */
	protected String getProcessorResult(Class<? extends AnnotationProcessor> processor) {
		String propertyName = BaseProcessor.getPropertyName(processor);
		String result = System.getProperty(propertyName);
		System.clearProperty(propertyName);
		return result;
	}
	
	protected void expectingMarkers(String[] messages)
	{	
		final IMarker[] markers = getAllAPTMarkers(env.getWorkspaceRootPath());
		final Set<String> expectedMessages = new HashSet<String>();
		for(String msg : messages ){
			expectedMessages.add(msg);
		}
		boolean fail = false;
		try{
			for( IMarker marker : markers ){
				final String markerMsg = (String)marker.getAttribute(IMarker.MESSAGE);
				if( expectedMessages.contains(markerMsg) )
					expectedMessages.remove(markerMsg);
				else{
					fail = true;
					break;
				}
			}
			if( !expectedMessages.isEmpty() )
				fail = true;
		}catch(CoreException ce){
			assertTrue("unexpected core exception" + ce.getMessage(), false); //$NON-NLS-1$
		}
		if( fail )
			assertEquals(concate(messages), concate(markers));
	}
	
	protected void expectingNoMarkers() {
		expectingNoMarkers(env.getWorkspaceRootPath());
	}
	
	protected void expectingNoMarkers(IPath path)
	{
		final IMarker[] markers = getAllAPTMarkers(path);
		
		if( markers != null && markers.length != 0 ){
			try{
				assertTrue("unexpected marker(s) : " + markers[0].getAttribute(IMarker.MESSAGE), false); //$NON-NLS-1$
			}
			catch(CoreException ce){
				assertTrue("unexpected core exception" + ce.getMessage(), false); //$NON-NLS-1$
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	protected IMarker[] getAllAPTMarkers(IPath path){
		IResource resource;
		if(path.equals(env.getWorkspaceRootPath())){
			resource = env.getWorkspace().getRoot();
		} else {
			IProject p = env.getProject(path);
			if(p != null && path.equals(p.getFullPath())) {
				resource = env.getProject(path.lastSegment());
			} else if(path.getFileExtension() == null) {
				resource = env.getWorkspace().getRoot().getFolder(path);
			} else {
				resource = env.getWorkspace().getRoot().getFile(path);
			}
		}
		try {
			IMarker[] markers = null;
			int total = 0;
			final IMarker[] processorMarkers = resource.findMarkers(AptPlugin.APT_BATCH_PROCESSOR_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
			total = processorMarkers.length;
			markers = processorMarkers;
				
			final IMarker[] factoryPathMarkers = resource.findMarkers(AptPlugin.APT_LOADER_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);			
			if( factoryPathMarkers.length != 0 ){
				if( total != 0 ){
					final int len = factoryPathMarkers.length;
					final IMarker[] temp = new IMarker[len + total ];
					System.arraycopy(markers, 0, temp, 0, total);
					System.arraycopy(factoryPathMarkers, 0, temp, total, len);
					markers = temp;
					total += len;
				}
				else
					markers = factoryPathMarkers;
			}
			final IMarker[] configMarkers = resource.findMarkers(AptPlugin.APT_CONFIG_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);			
			if( configMarkers.length != 0 ){
				if( total != 0 ){
					final int len = configMarkers.length;
					final IMarker[] temp = new IMarker[len + total];
					System.arraycopy(markers, 0, temp, 0, total);
					System.arraycopy(configMarkers, 0, temp, total, len);
					markers = temp;
					total += len;
				}
				else
					markers = configMarkers;
			}
			return markers;
		} catch(CoreException e){
			return null;
		}
	}

	/** 
	 * Verifies that the given element has specifics problems and
	 * only the given problems.
	 * @see Tests#expectingOnlySpecificProblemsFor(IPath, Problem[]), and
	 * @see Tests#expectingSpecificProblemsFor(IPath, Problem[], boolean).
	 * Unfortunately this variant isn't implemented there.
	 */
	protected void expectingOnlySpecificProblemsFor(IPath root, ExpectedProblem[] expectedProblems) {
		if (DEBUG)
			printProblemsFor(root);
	
		Problem[] rootProblems = env.getProblemsFor(root, AptPlugin.APT_COMPILATION_PROBLEM_MARKER);
	
		for (int i = 0; i < expectedProblems.length; i++) {
			ExpectedProblem expectedProblem = expectedProblems[i];
			boolean found = false;
			for (int j = 0; j < rootProblems.length; j++) {
				if(expectedProblem.equalsProblem(rootProblems[j])) {
					found = true;
					rootProblems[j] = null;
					break;
				}
			}
			if (!found) {
				printProblemsFor(root);
			}
			assertTrue("problem not found: " + expectedProblem.toString(), found); //$NON-NLS-1$
		}
		for (int i = 0; i < rootProblems.length; i++) {
			if(rootProblems[i] != null) {
				printProblemsFor(root);
				assertTrue("unexpected problem: " + rootProblems[i].toString(), false); //$NON-NLS-1$
			}
		}
	}
	
	/** Verifies that the given element has specific problems.
	 */
	protected void expectingSpecificProblemsFor(IPath root, ExpectedProblem[] problems) {
		if (DEBUG)
			printProblemsFor(root);

		Problem[] rootProblems = env.getProblemsFor(root, AptPlugin.APT_COMPILATION_PROBLEM_MARKER);
		next : for (int i = 0; i < problems.length; i++) {
			ExpectedProblem problem = problems[i];
			for (int j = 0; j < rootProblems.length; j++) {
				Problem rootProblem = rootProblems[j];
				if (rootProblem != null) {
					if (problem.equalsProblem(rootProblem)) {
						rootProblems[j] = null;
						continue next;
					}
				}
			}
			for (int j = 0; j < rootProblems.length; j++) {
				Problem pb = rootProblems[j];
				if (pb == null) continue;
				System.out.print("got pb:		new Problem(\"" + pb.getLocation() + "\", \"" + pb.getMessage() + "\", \"" + pb.getResourcePath() + "\"");
				System.out.print(", " + pb.getStart() + ", " + pb.getEnd() +  ", " + pb.getCategoryId());
				System.out.println(")");
			}
			assertTrue("missing expected problem : " + problem, false);
		}
	}
	
	/** Verifies that the given element has a specific problem and
	 * only the given problem.
	 */
	protected void expectingOnlySpecificProblemFor(IPath root, ExpectedProblem problem) {
		expectingOnlySpecificProblemsFor(root, new ExpectedProblem[] { problem });
	}
	
	protected static void sleep( long millis )
	{	
		long end = System.currentTimeMillis() + millis;
		while ( millis > 0 )
		{
			try
			{
				Thread.sleep( millis );
			}
			catch ( InterruptedException ie )
			{}
			millis = end - System.currentTimeMillis();
		}
	}
	

	
}
