/*******************************************************************************
 * Copyright (c) 2000, 2010 BEA Systems, Inc, IBM Corporation, and others
 *
 * 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.tests;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceDescription;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.jdt.apt.core.internal.AptPlugin;
import org.eclipse.jdt.apt.core.internal.util.FileSystemUtil;
import org.eclipse.jdt.apt.tests.plugin.AptTestsPlugin;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.tests.util.Util;

public class TestUtil
{
	
	private static final String BIN_EXT = "/bin-ext"; //$NON-NLS-1$
	private static final String BIN_ANNOTATIONS = "/bin-annotations"; //$NON-NLS-1$

	private static File ANNO_JAR = null;

	/**
	 * Returns the annotation jar, creating it if it hasn't already been created.
	 * @return the java.io.File of the jar that was created.
	 */
	public static File createAndAddAnnotationJar( IJavaProject project )
		throws IOException, JavaModelException
	{
		if (ANNO_JAR == null) {
			// The jar file will be created in the state location, e.g., .metadata/
			IPath statePath = AptPlugin.getPlugin().getStateLocation();
			IPath jarPath = statePath.append("org.eclipse.jdt.apt.tests.TestUtil.jar");
			ANNO_JAR = new File(jarPath.toOSString());
			String classesJarPath = ANNO_JAR.getAbsolutePath();
			
			if (null != getFileInPlugin( AptTestsPlugin.getDefault(), new Path(BIN_ANNOTATIONS) )) {
				// We're in a dev environment, where we jar up the classes from the plugin project
				FileFilter filter = new PackageFileFilter(
						ANNOTATIONS_PKG, getAnnotationsClassesDir());
				Map<File, FileFilter> files = Collections.singletonMap(
						new File(getAnnotationsClassesDir()), filter);
				zip( classesJarPath, files );
			}
			else {
				// We're in a releng environment, where we copy the already-built jar
				File aptJarFile = getFileInPlugin( AptTestsPlugin.getDefault(), new Path("/apt.jar")); 
				if(null == aptJarFile) {
					throw new FileNotFoundException("Could not find apt.jar file in org.eclipse.jdt.apt.tests plugin");
				}
				moveFile(aptJarFile, classesJarPath);
			}

			ANNO_JAR.deleteOnExit();
		}
		
		addLibraryEntry( project, new Path(ANNO_JAR.getAbsolutePath()), null /*srcAttachmentPath*/, 
			null /*srcAttachmentPathRoot*/, true );
		
		return ANNO_JAR;
	}
	
	/**
	 * Looks for the apt.jar that is defined in the build.properties 
	 * and available when the plugin is built deployed. 
	 * (currently when the plugin is built using releng the /bin directory classes are not available)
	 * 
	 * else it creates an annotation jar containing annotations and processors
	 * from the "external.annotations" package, and adds it to the project.
	 * Classes will be found under [project]/binext, and manifest will be
	 * drawn from [project]/srcext/META-INF.  
	 * This jar is meant to represent an annotation jar file not 
	 * wrapped within a plugin.  Note that adding a jar to a project makes
	 * its classes visible to the compiler but does NOT automatically cause 
	 * its annotation processors to be loaded.
	 * @return the java.io.File of the jar that was created.
	 */
	public static File createAndAddExternalAnnotationJar( 
			IJavaProject project  )
		throws IOException, JavaModelException
	{
		// create temporary file
		File jarFile = File.createTempFile("org.eclipse.jdt.apt.tests.TestUtil", ".jar");  //$NON-NLS-1$//$NON-NLS-2$
		String classesJarPath = jarFile.getAbsolutePath();
		
		File extBinDir = getFileInPlugin( AptTestsPlugin.getDefault(), new Path(BIN_EXT)); 
		if(null != extBinDir) {
			
			//create zip file in temp file location
			FileFilter classFilter = new PackageFileFilter(
					EXTANNOTATIONS_PKG, getPluginExtClassesDir());
			FileFilter manifestFilter = new PackageFileFilter(
					"META-INF", getPluginExtSrcDir()); //$NON-NLS-1$
			Map<File, FileFilter> files = new HashMap<File, FileFilter>(2);
			files.put(new File( getPluginExtClassesDir() ), classFilter);
			files.put(new File( getPluginExtSrcDir() ), manifestFilter);
			zip( classesJarPath, files );
			
		} else {
		
			File extJarFile = getFileInPlugin( AptTestsPlugin.getDefault(), new Path("/aptext.jar")); 
			if(null != extJarFile) {
				
				// move extapt.jar to classesJarPath file
				moveFile(extJarFile, classesJarPath);
			
			} else {
				
				throw new FileNotFoundException("Could not find aptext.jar file in org.eclipse.jdt.apt.tests plugin");
			}
			
		}
		
		addLibraryEntry( project, new Path(classesJarPath), null /*srcAttachmentPath*/, 
				null /*srcAttachmentPathRoot*/, true );
		
		
		// This file will be locked until GC takes care of unloading the
		// annotation processor classes, so we can't delete it ourselves.
		jarFile.deleteOnExit();
		return jarFile;
		
	}
	
	/**
	 * In automated tests, newly created resources are often locked by the
	 * Java Indexer and cannot be deleted right away.  The methods in
	 * org.eclipse.jdt.core.tests.util.Util work around this by catching
	 * and retrying until success.  This is a convenience method to fill a
	 * hole in the Util API.
	 * @return an IStatus that describes if the deletion was successful
	 */
	public static IStatus deleteFile(IPath path) {
		IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
		return Util.delete(file);
	}
	
	/**
     * Set the autobuild to the value of the parameter and
     * return the old one.  This is a workaround for a synchronization
     * problem: thread A creates a project, thus spawning thread B to
     * do an autobuild.  Thread A goes on to configure the project's
     * classpath; at the same time, thread B calls APT, which configures
     * the project's classpath.  Access to the classpath is not
     * synchronized, so there's a race for which thread's modification 
     * wins.  We work around this by disabling autobuild.
     * 
     * @param state the value to be set for autobuilding.
     * @return the old value of the autobuild state
     */
    public static boolean enableAutoBuild(boolean state) {
        IWorkspace workspace= ResourcesPlugin.getWorkspace();
        IWorkspaceDescription desc= workspace.getDescription();
        boolean isAutoBuilding= desc.isAutoBuilding();
        if (isAutoBuilding != state) {
            desc.setAutoBuilding(state);
            try {
				workspace.setDescription(desc);
			} catch (CoreException e) {
				e.printStackTrace();
			}
        }
        return isAutoBuilding;
    }
    
	public static IPath getProjectPath( IJavaProject project )
	{
		return project.getResource().getLocation();
	}
	
	public static String getAnnotationsClassesDir()
	{
		return getFileInPlugin( AptTestsPlugin.getDefault(), new Path( BIN_ANNOTATIONS ) ) //$NON-NLS-1$
			.getAbsolutePath();
	}

	public static String getPluginExtClassesDir()
	{
		return getFileInPlugin( AptTestsPlugin.getDefault(), new Path( BIN_EXT ) ) //$NON-NLS-1$
			.getAbsolutePath();
	}

	public static String getPluginExtSrcDir()
	{
		return getFileInPlugin( AptTestsPlugin.getDefault(), new Path( "/src-ext" ) ) //$NON-NLS-1$
			.getAbsolutePath();
	}

	/**
	 * 
	 * @param plugin The Plugin to get file from
	 * @param path The path to the file in the Plugin
	 * @return File object if found, null otherwise
	 */
	public static java.io.File getFileInPlugin(Plugin plugin, IPath path)
	{
		try
		{
			URL installURL = plugin.getBundle().getEntry( path.toString() );
			if(null == installURL)
				return null; // File Not found
			
			URL localURL = FileLocator.toFileURL( installURL );
			return new java.io.File( localURL.getFile() );
		}
		catch( IOException e )
		{
			return null;
		}
	}

	/**
	 * Could use File.renameTo(File) but it's platform dependant.
	 * 
	 * @param from - The file to move
	 * @param path - The path to move it to
	 */
	public static void moveFile(File from , String toPath)
		throws FileNotFoundException, IOException {
		
		FileInputStream fis = null;
		FileOutputStream fos = null; 
		try
		{
			fis = new FileInputStream( from );
			fos = new FileOutputStream(new File(toPath));
			int b;
			while ( ( b = fis.read() ) != -1)
				fos.write( b );
		} 
		finally
		{
			if ( fis != null ) fis.close();
			if ( fos != null ) fos.close();
		}
	}
	
	/**
	 * Create a zip file and add contents.
	 * @param zipPath the zip file
	 * @param input a map of root directories and corresponding filters.  Each
	 * root directory will be searched, and any files that pass the filter will
	 * be added to the zip file.
	 * @throws IOException
	 */
	public static void zip(String zipPath, Map<File, FileFilter> input)
		throws IOException
	{
		ZipOutputStream zip = null;
		try
		{
			zip = new ZipOutputStream( new FileOutputStream( zipPath ) );
			// +1 for last slash
			for (Map.Entry<File, FileFilter> e : input.entrySet()) {
				zip( zip, e.getKey(), e.getKey().getPath().length() + 1, e.getValue() );
			}
		}
		finally
		{
			if( zip != null )
			{
				zip.close();
			}
		}
	}
	
	private static void zip(ZipOutputStream zip, File dir, int rootPathLength,
		FileFilter filter) throws IOException
	{
		String[] list = dir.list();
		if( list != null )
		{
			for( int i = 0, length = list.length; i < length; i++ )
			{
				String name = list[i];
				File file = new File( dir, name );
				if( filter == null || filter.accept( file ) )
				{
					if( file.isDirectory() )
					{
						zip( zip, file, rootPathLength, filter );
					}
					else
					{
						String path = file.getPath();
						path = path.substring( rootPathLength );
						ZipEntry entry = new ZipEntry( path.replace( '\\', '/' ) );
						zip.putNextEntry( entry );
						zip.write( getBytesFromFile( file ) );
						zip.closeEntry();
					}
				}
			}
		}
	}
	
	private static byte[] getBytesFromFile( File f )
		throws IOException
	{
		FileInputStream fis = null;
		ByteArrayOutputStream baos = null;
		byte[] rtrn = new byte[0]; 
		try
		{
			fis = new FileInputStream( f );
			baos = new ByteArrayOutputStream();
			int b;
			while ( ( b = fis.read() ) != -1)
				baos.write( b );
			rtrn = baos.toByteArray();
		}
		finally
		{
			if ( fis != null ) fis.close();
			if ( baos != null ) baos.close();
		}
		return rtrn;
	
	}
	
	public static void unzip (File srcZip, File destDir) throws IOException {
		ZipFile zf = new ZipFile(srcZip);
		for (Enumeration<? extends ZipEntry> entries = zf.entries(); entries.hasMoreElements();) {
			ZipEntry entry = entries.nextElement();
			String name = entry.getName();
			File dest = new File(destDir, name);
			if (entry.isDirectory()) {
				FileSystemUtil.mkdirs(dest);
			}
			else {
				File parent = dest.getParentFile();
				FileSystemUtil.mkdirs(parent);
				InputStream from = null;
	            OutputStream to = null;
	            try {
	                from = zf.getInputStream(entry);
	                to = new FileOutputStream(dest);
	                byte[] buffer = new byte[4096];
	                int bytesRead;
	                while ((bytesRead = from.read(buffer)) != -1) {
	                    to.write(buffer, 0, bytesRead);
	                }
	            }
	            finally {
	                if (from != null) try {from.close();} catch (IOException ioe){}
	                if (to != null) try {to.close();} catch (IOException ioe) {}
	            }
			}
		}
	}
	
	public static void unzip (ZipInputStream srcZip, File destDir) throws IOException {
		ZipEntry entry;
		while ((entry = srcZip.getNextEntry()) != null) {
			String name = entry.getName();
			File dest = new File(destDir, name);
			if (entry.isDirectory()) {
				FileSystemUtil.mkdirs(dest);
			}
			else {
				File parent = dest.getParentFile();
				FileSystemUtil.mkdirs(parent);
	            OutputStream to = null;
	            try {
	                to = new FileOutputStream(dest);
	                byte[] buffer = new byte[4096];
	                int bytesRead;
	                while ((bytesRead = srcZip.read(buffer)) != -1) {
	                    to.write(buffer, 0, bytesRead);
	                }
	            }
	            finally {
                    srcZip.closeEntry();
	                if (to != null) try {to.close();} catch (IOException ioe) {}
	            }
			}
		}
	}
	
	
	public static void addLibraryEntry(IJavaProject project, IPath path, IPath srcAttachmentPath, IPath srcAttachmentPathRoot, boolean exported) throws JavaModelException{
		IClasspathEntry[] entries = project.getRawClasspath();
		int length = entries.length;
		IClasspathEntry newPathEntry = JavaCore.newLibraryEntry(
				path, 
				srcAttachmentPath, 
				srcAttachmentPathRoot, 
				exported); 
		for(int i = 0; i < length; i++) {
			//check for duplicates (Causes JavaModelException) - return if path already exists
			if(newPathEntry.equals(entries[i]))
				return;
		}
		System.arraycopy(entries, 0, entries = new IClasspathEntry[length + 1], 1, length);
		entries[0] = newPathEntry;
		project.setRawClasspath(entries, null);
	}
	
	
	private static class PackageFileFilter implements FileFilter {
		private final String[] _packageParts;
		private final Path _binDir;
		
		/**
		 * Select only those files under a certain package.
		 * @param packageSubset a partial package name, such as 
		 * "org.eclipse.jdt.apt.tests.annotations".
		 * @param binDir the absolute path of the directory 
		 * in which the compiled classes are to be found.
		 */
		public PackageFileFilter(String packageSubset, String binDir) {
			_packageParts = packageSubset.split("\\."); //$NON-NLS-1$
			_binDir = new Path(binDir);
		}
		
		public boolean accept(File pathname)
		{
			IPath f = new Path( pathname.getAbsolutePath() );

			int nsegments = f.matchingFirstSegments( _binDir );
			boolean ok = true;
			int min = Math.min( f.segmentCount() - nsegments,
					_packageParts.length );
			for( int i = nsegments, j = 0; j < min; i++, j++ )
			{
				if( !f.segment( i ).equals( _packageParts[j] ) )
				{
					ok = false;
					break;
				}
			}
			return ok;
		}
	}
	
	public static final String ANNOTATIONS_PKG = 
		"org.eclipse.jdt.apt.tests.annotations"; //$NON-NLS-1$

	public static final String EXTANNOTATIONS_PKG = 
		"org.eclipse.jdt.apt.tests.external.annotations"; //$NON-NLS-1$

}
