/*******************************************************************************
 *  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.File;
import java.io.IOException;
import java.util.*;

public class PackStep extends CommandStep {

	protected static String packCommand = null;
	private static Boolean canPack = null;

	private Set exclusions = Collections.EMPTY_SET;

	public static boolean canPack() {
		if (canPack != null)
			return canPack.booleanValue();

		String[] locations = Utils.getPack200Commands("pack200"); //$NON-NLS-1$
		if (locations == null) {
			canPack = Boolean.FALSE;
			packCommand = null;
			return false;
		}

		int result;
		for (int i = 0; i < locations.length; i++) {
			if (locations[i] == null)
				continue;
			result = execute(new String[] {locations[i], "-V"}); //$NON-NLS-1$
			if (result == 0) {
				packCommand = locations[i];
				canPack = Boolean.TRUE;
				return true;
			}
		}

		canPack = Boolean.FALSE;
		return false;
	}

	public PackStep(Properties options) {
		super(options, null, null, false);
		exclusions = Utils.getPackExclusions(options);
	}

	public PackStep(Properties options, boolean verbose) {
		super(options, null, null, verbose);
		exclusions = Utils.getPackExclusions(options);
	}

	public String recursionEffect(String entryName) {
		if (canPack() && entryName.endsWith(".jar") && !exclusions.contains(entryName)) { //$NON-NLS-1$
			return entryName + Utils.PACKED_SUFFIX;
		}
		return null;
	}

	public File preProcess(File input, File workingDirectory, List containers) {
		return null;
	}

	public File postProcess(File input, File workingDirectory, List containers) {
		if (canPack() && packCommand != null) {
			Properties inf = Utils.getEclipseInf(input, verbose);
			if (!shouldPack(input, containers, inf))
				return null;
			File outputFile = new File(workingDirectory, input.getName() + Utils.PACKED_SUFFIX);
			try {
				String[] cmd = getCommand(input, outputFile, inf, containers);
				int result = execute(cmd, verbose);
				if (result != 0 && verbose)
					System.out.println("Error: " + result + " was returned from command: " + Utils.concat(cmd)); //$NON-NLS-1$ //$NON-NLS-2$
			} catch (IOException e) {
				if (verbose)
					e.printStackTrace();
				return null;
			}
			return outputFile;
		}
		return null;
	}

	protected boolean shouldPack(File input, List containers, Properties inf) {
		//1: exclude by containers
		// innermost jar is first on the list, it can override outer jars
		for (Iterator iterator = containers.iterator(); iterator.hasNext();) {
			Properties container = (Properties) iterator.next();
			if (container.containsKey(Utils.MARK_EXCLUDE_CHILDREN_PACK)) {
				if (Boolean.valueOf(container.getProperty(Utils.MARK_EXCLUDE_CHILDREN_PACK)).booleanValue()) {
					if (verbose)
						System.out.println(input.getName() + " is excluded from pack200 by its containers."); //$NON-NLS-1$
					return false;
				}
				break;
			}
		}

		//2: excluded by self
		if (inf != null && inf.containsKey(Utils.MARK_EXCLUDE_PACK) && Boolean.valueOf(inf.getProperty(Utils.MARK_EXCLUDE_PACK)).booleanValue()) {
			if (verbose)
				System.out.println("Excluding " + input.getName() + " from " + getStepName()); //$NON-NLS-1$ //$NON-NLS-2$
			return false;
		}

		return true;
	}

	protected String[] getCommand(File input, File outputFile, Properties inf, List containers) throws IOException {
		String[] cmd = null;
		String arguments = getArguments(input, inf, containers);
		if (arguments != null && arguments.length() > 0) {
			String[] args = Utils.toStringArray(arguments, ","); //$NON-NLS-1$
			cmd = new String[3 + args.length];
			cmd[0] = packCommand;
			System.arraycopy(args, 0, cmd, 1, args.length);
			cmd[cmd.length - 2] = outputFile.getCanonicalPath();
			cmd[cmd.length - 1] = input.getCanonicalPath();
		} else {
			cmd = new String[] {packCommand, outputFile.getCanonicalPath(), input.getCanonicalPath()};
		}
		return cmd;
	}

	protected String getArguments(File input, Properties inf, List containers) {
		//1: Explicitly marked in our .inf file
		if (inf != null && inf.containsKey(Utils.PACK_ARGS)) {
			return inf.getProperty(Utils.PACK_ARGS);
		}

		//2: Defaults set in one of our containing jars
		for (Iterator iterator = containers.iterator(); iterator.hasNext();) {
			Properties container = (Properties) iterator.next();
			if (container.containsKey(Utils.DEFAULT_PACK_ARGS)) {
				return container.getProperty(Utils.DEFAULT_PACK_ARGS);
			}
		}

		//3: Set by name in outside pack.properties file
		Properties options = getOptions();
		String argsKey = input.getName() + Utils.PACK_ARGS_SUFFIX;
		if (options.containsKey(argsKey)) {
			return options.getProperty(argsKey);
		}

		//4: Set by default in outside pack.properties file
		if (options.containsKey(Utils.DEFAULT_PACK_ARGS)) {
			return options.getProperty(Utils.DEFAULT_PACK_ARGS);
		}

		return ""; //$NON-NLS-1$
	}

	public String getStepName() {
		return "Pack"; //$NON-NLS-1$
	}

	public void adjustInf(File input, Properties inf, List containers) {
		if (input == null || inf == null)
			return;

		//don't be verbose to check if we should mark the inf
		boolean v = verbose;
		verbose = false;
		if (!shouldPack(input, containers, inf)) {
			verbose = v;
			return;
		}
		verbose = v;

		//mark as conditioned if not previously marked.  A signed jar is assumed to be previously conditioned.
		if (inf.getProperty(Utils.MARK_PROPERTY) == null) {
			inf.put(Utils.MARK_PROPERTY, "true"); //$NON-NLS-1$

			//record arguments used
			String arguments = inf.getProperty(Utils.PACK_ARGS);
			if (arguments == null) {
				arguments = getArguments(input, inf, containers);
				if (arguments != null && arguments.length() > 0)
					inf.put(Utils.PACK_ARGS, arguments);
			}
		}
	}
}
