/*******************************************************************************
 * Copyright (c) 2000, 2005 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.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.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;

public class TestUtil
{
	
	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") )) {
				// We're in a dev environment, where we jar up the classes from the plugin project
				FileFilter filter = new PackageFileFilter(
						ANNOTATIONS_PKG, getPluginClassesDir());
				Map<File, FileFilter> files = Collections.singletonMap(
						new File(getPluginClassesDir()), 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("/binext")); 
		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;
		
	}
	
	/**
     * 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 getPluginClassesDir()
	{
		return getFileInPlugin( AptTestsPlugin.getDefault(), new Path( "/bin" ) ) //$NON-NLS-1$
			.getAbsolutePath();
	}

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

	public static String getPluginExtSrcDir()
	{
		return getFileInPlugin( AptTestsPlugin.getDefault(), new Path( "/srcext" ) ) //$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$

}
