package org.eclipse.update.examples.buildzip;

/*
 * (c) Copyright IBM Corp. 2000, 2002.
 * All Rights Reserved.
 */ 
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringBufferInputStream;
import java.net.URL;
import java.util.Properties;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;

import org.eclipse.update.core.*;
import org.eclipse.update.core.ContentReference;
import org.eclipse.update.core.IFeature;
import org.eclipse.update.core.IFeatureContentProvider;
import org.eclipse.update.core.IPluginEntry;
import org.eclipse.update.core.JarContentReference;
import org.eclipse.update.core.model.InstallAbortedException;

/**
 * Converts eclipse build .zip files into packaged feature
 */
public class BuildZipConverter {

	public static void main(String[] args) {
		if (args.length <=0) {
			System.out.println("Usage:     BuildZipConverter <path to the zip file>.\r\nExample: BuildZipConverter d:/download/integration-eclipse-SDK-20020109-win32.zip");
			return;
		}
		try {
			URL buildzip = new URL(("file:"+args[0]).replace(File.separatorChar, '/'));
			BuildZipFeatureFactory factory = new BuildZipFeatureFactory();
			IFeature feature = factory.createFeature(buildzip, null);
			IFeatureContentProvider provider = feature.getFeatureContentProvider();
			
			ContentReference[] refs = provider.getFeatureEntryContentReferences(null);
			
			File site = new File((args[0]+".packaged/").replace('/',File.separatorChar));
			site.mkdirs();
			File featuresDir = new File(site,"features");
			featuresDir.mkdirs();
			File pluginsDir = new File(site, "plugins");
			pluginsDir.mkdirs();
			
			File jarFile = new File(featuresDir,feature.getVersionedIdentifier()+".jar");
			System.out.println("writing feature archive: "+feature.getVersionedIdentifier()+".jar");
			writeJar(jarFile, refs, feature, null, null);
			JarContentReference jar = new JarContentReference("build.zip",buildzip);
			Properties manifest = getBuildManifest(jar);
			
			IPluginEntry[] plugins = feature.getPluginEntries();
			for (int i=0; i<plugins.length; i++) {
				refs = provider.getPluginEntryContentReferences(plugins[i], null);
				jarFile = new File(pluginsDir,plugins[i].getVersionedIdentifier()+".jar");
				System.out.println("writing plugin archive: "+plugins[i].getVersionedIdentifier()+".jar");
				writeJar(jarFile, refs, feature, plugins[i].getVersionedIdentifier().getIdentifier(), manifest);
			}
			
			writeSiteManifest(site, feature);
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void writeJar(File jarFile,ContentReference[] refs, IFeature feature, String pluginId, Properties manifest) {
			
		JarOutputStream jos = null;
		FileOutputStream os = null;
		InputStream is = null;
		
		try {
			os = new FileOutputStream(jarFile);
			jos = new JarOutputStream(os);
			JarEntry entry = null;
			String buf = null;
			StringBufferInputStream sbis = null;
			
			// write jar manifest (first entry in output stream)
			buf = "Manifest-Version: 1.0\nCreated-By: 2.0.0 (www.eclipse.org Feature Packager)\n";
			sbis = new StringBufferInputStream(buf);
			entry = new JarEntry("META-INF/MANIFEST.MF");
			jos.putNextEntry(entry);
			Utilities.copy(sbis,jos,null);
			sbis.close();
			
			// jar up the references
			for (int i=0; i<refs.length; i++) {
				String id = refs[i].getIdentifier();
				entry = new JarEntry(id);
				jos.putNextEntry(entry);
				is = refs[i].getInputStream();
				Utilities.copy(is,jos,null);
				is.close(); is = null;
			}
			
			// for plugin jars, write build manifest
			if (pluginId != null && manifest != null) {
				String key = "plugin@"+pluginId;
				String value = manifest.getProperty(key);
				if (value != null) {
					if (value.equals("HEAD")) {
						value += "-" + feature.getVersionedIdentifier().getVersion().getMajorComponent();
					}
					buf = key + "=" + value;
					sbis = new StringBufferInputStream(buf);
					entry = new JarEntry("buildmanifest.properties");
					jos.putNextEntry(entry);
					Utilities.copy(sbis,jos,null);
					sbis.close();
				}
			}
			
			// close jar
			jos.close(); jos = null; os = null;
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			if (is != null) 
				try {is.close();} catch(IOException e) {}
				
			if (jos != null) 
				try {jos.close();} catch(IOException e) {}
			else if (os != null)
				try {os.close();} catch(IOException e) {}
		}		
	}
	
	public static void writeSiteManifest(File site, IFeature feature) throws IOException, InstallAbortedException {
		File manifest = new File(site, "site.xml");
		FileOutputStream os = new FileOutputStream(manifest);
		String siteXML = "<site>\n   <feature url=\"features/"+feature.getVersionedIdentifier().toString()+".jar\"/>\n</site>";
		StringBufferInputStream sbis = new StringBufferInputStream(siteXML);
		Utilities.copy(sbis,os,null);
		os.close();
		sbis.close();
	}
	
	public static Properties getBuildManifest(JarContentReference jar) throws IOException {
		ContentReference manifestEntry = jar.peek("eclipse/buildmanifest.properties",null/*ContentSelector*/, null/*ProgressMonitor*/);
		InputStream is = null;
		Properties props = null;
		try {
			props = new Properties();
			is = manifestEntry.getInputStream();
			props.load(is);
		} finally {
			if (is != null) try{ is.close(); } catch(IOException e) {}
		}
		return props;
	}
}
