/*******************************************************************************
 * 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.optimizers.jardelta;

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

public class DeltaComputer {
	private File target;
	private File base;
	private File destination;
	private ZipFile baseJar;
	private ZipFile targetJar;
	private Set baseEntries;
	private ArrayList additions;
	private ArrayList changes;
	private ZipFile manifestJar = null;

	public DeltaComputer(File base, File target, File destination) {
		this.base = base;
		this.target = target;
		this.destination = destination;
	}

	public void run() throws IOException {
		try {
			if (!openJars())
				return;
			computeDelta();
			writeDelta();
		} finally {
			closeJars();
		}
	}

	private void writeDelta() {
		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("META-INF/MANIFEST.MF"), manifestJar, true);
				// write out the removals.  These are all the entries left in the baseEntries
				// since they were not seen in the targetJar.  Here just write out an empty
				// entry with a name that signals the delta processor to delete.
				for (Iterator i = baseEntries.iterator(); i.hasNext();)
					writeEntry(result, new ZipEntry(((String) i.next()) + ".delete"), null, false);
				// write out the additions.
				for (Iterator i = additions.iterator(); i.hasNext();)
					writeEntry(result, (ZipEntry) i.next(), targetJar, false);
				// write out the changes.
				for (Iterator i = changes.iterator(); i.hasNext();)
					writeEntry(result, (ZipEntry) i.next(), targetJar, 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("META-INF/MANIFEST.MF"))
			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 void computeDelta() throws IOException {
		changes = new ArrayList();
		additions = new ArrayList();
		// start out assuming that all the base entries are being removed
		baseEntries = getEntries(baseJar);
		for (Enumeration e = targetJar.entries(); e.hasMoreElements();)
			check((ZipEntry) e.nextElement(), targetJar);
	}

	private boolean openJars() {
		try {
			baseJar = new ZipFile(base);
			targetJar = new ZipFile(target);
		} 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 (targetJar != null)
			try {
				targetJar.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}

	/** 
	 * Compare the given entry against the base JAR to see if/how it differs.  Update the appropriate set
	 * based on the discovered difference.
	 * @param entry the entry to test
	 * @throws IOException 
	 */
	private void check(ZipEntry entry, ZipFile file) throws IOException {
		ZipEntry baseEntry = baseJar.getEntry(entry.getName());

		// remember the manifest if we see it
		checkForManifest(entry, file);
		// if there is no entry then this is an addition.  remember the addition and return;
		if (baseEntry == null) {
			additions.add(entry);
			return;
		}
		// now we know each JAR has an entry for the name, compare and see how/if they differ
		boolean changed = !equals(entry, baseEntry);
		if (changed)
			changes.add(entry);
		baseEntries.remove(baseEntry.getName());
	}

	// compare the two entries.  We already know that they have the same name.
	private boolean equals(ZipEntry entry, ZipEntry baseEntry) {
		if (entry.getSize() != baseEntry.getSize())
			return false;
		// make sure the entries are of the same type
		if (entry.isDirectory() != baseEntry.isDirectory())
			return false;
		// if the entries are files then compare the times.
		if (!entry.isDirectory())
			if (entry.getTime() != baseEntry.getTime())
				return false;
		return true;
	}

	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("META-INF/MANIFEST.MF"))
			manifestJar = jar;
	}
}
