/*******************************************************************************
 * Copyright (c) 2007 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 Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.equinox.internal.p2.artifact.processors.jardelta;

import java.io.*;
import java.util.*;
import java.util.zip.*;

public class DeltaApplier {
	private static final String DELETE_SUFFIX = ".delete"; //$NON-NLS-1$
	private static final String MANIFEST_ENTRY_NAME = "META-INF/MANIFEST.MF"; //$NON-NLS-1$
	private File delta;
	private File base;
	private File destination;
	private ZipFile baseJar;
	private ZipFile deltaJar;
	private Set baseEntries;
	private ZipFile manifestJar;

	public DeltaApplier(File base, File delta, File destination) {
		this.base = base;
		this.delta = delta;
		this.destination = destination;
	}

	public void run() {
		try {
			if (!openJars())
				return;
			applyDelta();
			writeResult();
		} finally {
			closeJars();
		}
	}

	private void applyDelta() {
		// start out assuming that all the base entries will be moved over.  
		baseEntries = getEntries(baseJar);
		// remove from the base all the entries that appear in the delta
		for (Enumeration e = deltaJar.entries(); e.hasMoreElements();) {
			ZipEntry entry = ((ZipEntry) e.nextElement());
			checkForManifest(entry, deltaJar);
			String name = entry.getName();
			if (name.endsWith(DELETE_SUFFIX)) {
				name = name.substring(0, name.length() - DELETE_SUFFIX.length());
				// if the manifest is being deleted, forget anyone who might have a manifest
				if (name.equalsIgnoreCase(MANIFEST_ENTRY_NAME))
					manifestJar = null;
			}
			baseEntries.remove(name);
		}
	}

	private void writeResult() {
		ZipOutputStream result = null;
		try {
			try {
				result = new ZipOutputStream(new FileOutputStream(destination));
				// if the delta includes the manifest, be sure to write it first
				if (manifestJar != null)
					writeEntry(result, manifestJar.getEntry(MANIFEST_ENTRY_NAME), manifestJar, true);
				// write out the things we know are staying from the base JAR
				for (Iterator i = baseEntries.iterator(); i.hasNext();) {
					ZipEntry entry = baseJar.getEntry((String) i.next());
					writeEntry(result, entry, baseJar, false);
				}
				// write out the changes/additions from the delta.
				for (Enumeration e = deltaJar.entries(); e.hasMoreElements();) {
					ZipEntry entry = (ZipEntry) e.nextElement();
					if (!entry.getName().endsWith(DELETE_SUFFIX))
						writeEntry(result, entry, deltaJar, false);
				}
			} finally {
				if (result != null)
					result.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
			return;
		}
	}

	private void writeEntry(ZipOutputStream result, ZipEntry entry, ZipFile sourceJar, boolean manifest) throws IOException {
		if (!manifest && entry.getName().equalsIgnoreCase(MANIFEST_ENTRY_NAME))
			return;
		// add the entry
		result.putNextEntry(entry);
		try {
			// if there is a sourceJar copy over the content for the entry into the result
			if (sourceJar != null) {
				InputStream contents = sourceJar.getInputStream(entry);
				try {
					transferStreams(contents, result);
				} finally {
					contents.close();
				}
			}
		} finally {
			result.closeEntry();
		}
	}

	/**
	 * Transfers all available bytes from the given input stream to the given
	 * output stream. Does not close either stream.
	 * 
	 * @param source
	 * @param destination
	 * @throws IOException
	 */
	public static void transferStreams(InputStream source, OutputStream destination) 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 {
			destination.flush();
		}
	}

	private boolean openJars() {
		try {
			baseJar = new ZipFile(base);
			deltaJar = new ZipFile(delta);
		} catch (IOException e) {
			return false;
		}
		return true;
	}

	private void closeJars() {
		if (baseJar != null)
			try {
				baseJar.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		if (deltaJar != null)
			try {
				deltaJar.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}

	private Set getEntries(ZipFile jar) {
		HashSet result = new HashSet(jar.size());
		for (Enumeration e = jar.entries(); e.hasMoreElements();) {
			ZipEntry entry = (ZipEntry) e.nextElement();
			checkForManifest(entry, jar);
			result.add(entry.getName());
		}
		return result;
	}

	/**
	 * Check to see if the given entry is the manifest.  If so, remember it for use when writing
	 * the resultant JAR.
	 * @param entry
	 * @param jar
	 */
	private void checkForManifest(ZipEntry entry, ZipFile jar) {
		if (entry.getName().equalsIgnoreCase(MANIFEST_ENTRY_NAME))
			manifestJar = jar;
	}

}
