/*******************************************************************************
 * Copyright (c) 2006, 2008 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:
 *     IBM - Initial API and implementation
 *******************************************************************************/
package org.eclipse.equinox.internal.p2.jarprocessor;

import java.io.*;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipException;

import org.eclipse.internal.provisional.equinox.p2.jarprocessor.JarProcessor;

/**
 * @author aniefer@ca.ibm.com
 *
 */
public class Utils {
	public static final String MARK_FILE_NAME = "META-INF/eclipse.inf"; //$NON-NLS-1$

	/*
	 * Properties found in outer pack.properties file
	 */
	//comma separated list of jars to exclude from sigining
	public static final String SIGN_EXCLUDES = "sign.excludes"; //$NON-NLS-1$
	//comma separated list of jars to exlclude from packing
	public static final String PACK_EXCLUDES = "pack.excludes"; //$NON-NLS-1$
	//Suffix used when specifying arguments to use when running pack200 on a jar
	public static final String PACK_ARGS_SUFFIX = ".pack.args"; //$NON-NLS-1$

	/*
	 * Properties found in both pack.properties and eclipse.inf
	 */
	//	Default arguments to use when running pack200.
	// Affects all jars when specified in pack.properties, affects children when specified in eclipse.inf
	public static final String DEFAULT_PACK_ARGS = "pack200.default.args"; //$NON-NLS-1$

	/*
	 * Properties found in eclipse.inf file
	 */
	//This jar has been conditioned with pack200
	public static final String MARK_PROPERTY = "pack200.conditioned"; //$NON-NLS-1$
	//Exclude this jar from processing
	public static final String MARK_EXCLUDE = "jarprocessor.exclude"; //$NON-NLS-1$
	//Exclude this jar from pack200
	public static final String MARK_EXCLUDE_PACK = "jarprocessor.exclude.pack"; //$NON-NLS-1$
	//Exclude this jar from signing
	public static final String MARK_EXCLUDE_SIGN = "jarprocessor.exclude.sign"; //$NON-NLS-1$
	//Exclude this jar's children from processing
	public static final String MARK_EXCLUDE_CHILDREN = "jarprocessor.exclude.children"; //$NON-NLS-1$
	//Exclude this jar's children from pack200
	public static final String MARK_EXCLUDE_CHILDREN_PACK = "jarprocessor.exclude.children.pack"; //$NON-NLS-1$
	//Exclude this jar's children from signing
	public static final String MARK_EXCLUDE_CHILDREN_SIGN = "jarprocessor.exclude.children.sign"; //$NON-NLS-1$
	//Arguments used in pack200 for this jar
	public static final String PACK_ARGS = "pack200.args"; //$NON-NLS-1$

	public static final String PACK200_PROPERTY = "org.eclipse.update.jarprocessor.pack200"; //$NON-NLS-1$
	public static final String JRE = "@jre"; //$NON-NLS-1$
	public static final String PATH = "@path"; //$NON-NLS-1$
	public static final String NONE = "@none"; //$NON-NLS-1$

	public static final String PACKED_SUFFIX = ".pack.gz"; //$NON-NLS-1$
	public static final String JAR_SUFFIX = ".jar"; //$NON-NLS-1$

	public static final FileFilter JAR_FILTER = new FileFilter() {
		public boolean accept(File pathname) {
			return pathname.isFile() && pathname.getName().endsWith(".jar"); //$NON-NLS-1$
		}
	};

	public static final FileFilter PACK_GZ_FILTER = new FileFilter() {
		public boolean accept(File pathname) {
			return pathname.isFile() && pathname.getName().endsWith(JarProcessor.PACKED_SUFFIX);
		}
	};

	public static void close(Object stream) {
		if (stream != null) {
			try {
				if (stream instanceof InputStream)
					((InputStream) stream).close();
				else if (stream instanceof OutputStream)
					((OutputStream) stream).close();
				else if (stream instanceof JarFile)
					((JarFile) stream).close();
			} catch (IOException e) {
				//ignore
			}
		}
	}

	/**
	 * get the set of commands to try to execute pack/unpack 
	 * @param cmd the command, either "pack200" or "unpack200"
	 * @return String [] or null
	 */
	public static String[] getPack200Commands(String cmd) {
		String[] locations = null;
		String prop = System.getProperty(PACK200_PROPERTY);
		String javaHome = System.getProperty("java.home"); //$NON-NLS-1$
		if (NONE.equals(prop)) {
			return null;
		} else if (JRE.equals(prop)) {
			locations = new String[] {javaHome + "/bin/" + cmd}; //$NON-NLS-1$
		} else if (PATH.equals(prop)) {
			locations = new String[] {cmd};
		} else if (prop == null) {
			locations = new String[] {javaHome + "/bin/" + cmd, cmd}; //$NON-NLS-1$ 
		} else {
			locations = new String[] {prop + "/" + cmd}; //$NON-NLS-1$
		}
		return locations;
	}

	/**
	 * Transfers all available bytes from the given input stream to the given
	 * output stream. Closes both streams if close == true, regardless of failure. 
	 * Flushes the destination stream if close == false
	 * 
	 * @param source
	 * @param destination
	 * @param close 
	 * @throws IOException
	 */
	public static void transferStreams(InputStream source, OutputStream destination, boolean close) throws IOException {
		source = new BufferedInputStream(source);
		destination = new BufferedOutputStream(destination);
		try {
			byte[] buffer = new byte[8192];
			while (true) {
				int bytesRead = -1;
				if ((bytesRead = source.read(buffer)) == -1)
					break;
				destination.write(buffer, 0, bytesRead);
			}
		} finally {
			if (close) {
				close(source);
				close(destination);
			} else {
				destination.flush();
			}
		}
	}

	/**
	 * Deletes all the files and directories from the given root down (inclusive).
	 * Returns false if we could not delete some file or an exception occurred
	 * at any point in the deletion.
	 * Even if an exception occurs, a best effort is made to continue deleting.
	 */
	public static boolean clear(java.io.File root) {
		boolean result = clearChildren(root);
		try {
			if (root.exists())
				result &= root.delete();
		} catch (Exception e) {
			result = false;
		}
		return result;
	}

	/**
	 * Deletes all the files and directories from the given root down, except for 
	 * the root itself.
	 * Returns false if we could not delete some file or an exception occurred
	 * at any point in the deletion.
	 * Even if an exception occurs, a best effort is made to continue deleting.
	 */
	public static boolean clearChildren(java.io.File root) {
		boolean result = true;
		if (root.isDirectory()) {
			String[] list = root.list();
			// for some unknown reason, list() can return null.  
			// Just skip the children If it does.
			if (list != null)
				for (int i = 0; i < list.length; i++)
					result &= clear(new java.io.File(root, list[i]));
		}
		return result;
	}

	public static Set getPackExclusions(Properties properties) {
		if (properties == null)
			return Collections.EMPTY_SET;

		String packExcludes = properties.getProperty(PACK_EXCLUDES);
		if (packExcludes != null) {
			String[] excludes = toStringArray(packExcludes, ","); //$NON-NLS-1$
			Set packExclusions = new HashSet();
			for (int i = 0; i < excludes.length; i++) {
				packExclusions.add(excludes[i]);
			}
			return packExclusions;
		}
		return Collections.EMPTY_SET;
	}

	public static Set getSignExclusions(Properties properties) {
		if (properties == null)
			return Collections.EMPTY_SET;
		String signExcludes = properties.getProperty(SIGN_EXCLUDES);
		if (signExcludes != null) {
			String[] excludes = toStringArray(signExcludes, ","); //$NON-NLS-1$
			Set signExclusions = new HashSet();
			for (int i = 0; i < excludes.length; i++) {
				signExclusions.add(excludes[i]);
			}
			return signExclusions;
		}
		return Collections.EMPTY_SET;
	}

	public static String concat(String[] array) {
		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < array.length; i++) {
			if (i > 0)
				buffer.append(' ');
			buffer.append(array[i]);
		}
		return buffer.toString();
	}

	public static String[] toStringArray(String input, String separator) {
		StringTokenizer tokenizer = new StringTokenizer(input, separator);
		int count = tokenizer.countTokens();
		String[] result = new String[count];
		for (int i = 0; i < count; i++) {
			result[i] = tokenizer.nextToken().trim();
		}
		return result;
	}

	/**
	 * Get the properties from the eclipse.inf file from the given jar.  If the file is not a jar, null is returned.
	 * If the file is a jar, but does not contain an eclipse.inf file, an empty Properties object is returned.
	 * @param jarFile
	 * @return The eclipse.inf properties for the given jar file
	 */
	public static Properties getEclipseInf(File jarFile, boolean verbose) {
		if (jarFile == null || !jarFile.exists()) {
			if (verbose)
				System.out.println("Failed to obtain eclipse.inf due to missing jar file: " + jarFile); //$NON-NLS-1$
			return null;
		}
		JarFile jar = null;
		try {
			jar = new JarFile(jarFile, false);
		} catch (ZipException e) {
			//not a jar, don't bother logging this.
			return null;
		} catch (IOException e) {
			if (verbose) {
				System.out.println("Failed to obtain eclipse.inf due to IOException: " + jarFile); //$NON-NLS-1$
				e.printStackTrace();
			}
			return null;
		}
		try {
			JarEntry mark = jar.getJarEntry(MARK_FILE_NAME);
			if (mark != null) {
				InputStream in = jar.getInputStream(mark);
				Properties props = new Properties();
				props.load(in);
				in.close();
				return props;
			}
			return new Properties();
		} catch (IOException e) {
			if (verbose) {
				System.out.println("Failed to obtain eclipse.inf due to IOException: " + jarFile); //$NON-NLS-1$
				e.printStackTrace();
			}
			return null;
		} finally {
			close(jar);
		}
	}

	public static boolean shouldSkipJar(File input, boolean processAll, boolean verbose) {
		Properties inf = getEclipseInf(input, verbose);
		if (inf == null) {
			//not a jar, could be a pack.gz
			return false;
		}
		String exclude = inf.getProperty(MARK_EXCLUDE);

		//was marked as exclude, we should skip
		if (exclude != null && Boolean.valueOf(exclude).booleanValue())
			return true;

		//process all was set, don't skip
		if (processAll)
			return false;

		//otherwise, we skip if not marked marked
		String marked = inf.getProperty(MARK_PROPERTY);
		return !Boolean.valueOf(marked).booleanValue();
	}

	/**
	 * Stores the given properties in the output stream.  We store the properties 
	 * in sorted order so that the signing hash doesn't change if the properties didn't change. 
	 * @param props
	 * @param stream
	 */
	public static void storeProperties(Properties props, OutputStream stream) {
		PrintStream printStream = new PrintStream(stream);
		printStream.print("#Processed using Jarprocessor\n"); //$NON-NLS-1$
		SortedMap sorted = new TreeMap(props);
		for (Iterator iter = sorted.keySet().iterator(); iter.hasNext();) {
			String key = (String) iter.next();
			printStream.print(key);
			printStream.print(" = "); //$NON-NLS-1$
			printStream.print(sorted.get(key));
			printStream.print("\n"); //$NON-NLS-1$

		}
		printStream.flush();
	}
}
