package org.eclipse.update.internal.core;
/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;

import org.eclipse.core.runtime.*;
import org.eclipse.update.core.*;

/**
 * Parse the default feature.xml
 */
public class FeaturePackaged extends Feature {

	private JarFile currentOpenJarFile = null;

	private URL rootURL;

	public static final String JAR_EXTENSION = ".jar";

	public static final FilenameFilter filter = new FilenameFilter(){
		 public boolean accept(File dir, String name){
		 	return name.endsWith(FeaturePackaged.JAR_EXTENSION);
		 }
	};

	/**
	 * @see IFeature#getRootURL()
	 * In general, the Root URL is the URL of teh Feature
	 * 
	 * The RootURL is used to calculate relative URL for teh feature
	 * In case of a file feature, you can just append teh relative path
	 * to the URL of teh feature
	 * 
	 * In case of a JAR file, you cannot *just* append the file 
	 * You have to transfrom the URL
	 * 
	 */
	public URL getRootURL() throws MalformedURLException, IOException, CoreException {
		
		// Extract the JAR file in the TEMP drive
		// and return the URL
		
		if (rootURL == null) {
			// install the Feature info into the TEMP drive
			// extract teh JAR file
			SiteFile tempSite = (SiteFile)SiteManager.getTempSite();
			
			InputStream inStream = null;
			String[] names = getStorageUnitNames();
			if (names != null) {
				openFeature();
				for (int j = 0; j < names.length; j++) {
					if ((inStream = getInputStreamFor(names[j])) != null)
						 tempSite.storeFeatureInfo(getIdentifier(), names[j], inStream);
				}
				closeFeature();
			}

			// get the path to the Feature, which is now pon the file system
			// <TempSite>/install/features/<id>_<ver>/
			// add '/' as it is a directory
			rootURL = UpdateManagerUtils.getURL(tempSite.getURL(),SiteFile.INSTALL_FEATURE_PATH+getIdentifier().toString()+"/",null);
		}
		return rootURL;
	}

	/**
	 * Constructor for DefaultPackagedFeature
	 */
	public FeaturePackaged(IFeature sourceFeature, ISite targetSite) throws CoreException {
		super(sourceFeature, targetSite);
	}

	/**
	 * Constructor for DefaultPackagedFeature
	 */
	public FeaturePackaged(URL url, ISite targetSite)  throws CoreException {
		super(url, targetSite);
	}

	/**
	 * @see AbstractFeature#getContentReferenceToInstall(IPluginEntry[])
	 */
	public String[] getContentReferenceToInstall(IPluginEntry[] pluginsToInstall) {
		String[] names = null;
		if (pluginsToInstall != null) {
			names = new String[pluginsToInstall.length];
			for (int i = 0; i < pluginsToInstall.length; i++) {
				names[i] = getArchiveID(pluginsToInstall[i]);
			}
		}
		return names;
	}

	/**
	 * @see AbstractFeature#getInputStreamFor(IPluginEntry,String)
	 */
	public InputStream getInputStreamFor(IPluginEntry pluginEntry, String name) throws CoreException {
		URL siteURL = getSite().getURL();
		InputStream result = null;

		try {
			// check if the site.xml had a coded URL for this plugin or if we
			// should look in teh default place to find it: <site>+/plugins/+archiveId
			String filePath = UpdateManagerUtils.getPath(((Site) getSite()).getURL(getArchiveID(pluginEntry)));						
			open(filePath);
			if (!(new File(filePath)).exists())
				throw new IOException("The File:" + filePath + "does not exist.");
			ZipEntry entry = currentOpenJarFile.getEntry(name);
			result = currentOpenJarFile.getInputStream(entry);
		} catch (Exception e) {
			String id = UpdateManagerPlugin.getPlugin().getDescriptor().getUniqueIdentifier();
			IStatus status = new Status(IStatus.ERROR, id, IStatus.OK, "Error opening :" + name + " in plugin archive:" + pluginEntry.getIdentifier().toString(), e);
			throw new CoreException(status);
		}
		return result;
	}

	/**
	 * @see AbstractFeature#getStorageUnitNames(IPluginEntry)
	 */
	public String[] getStorageUnitNames(IPluginEntry pluginEntry) throws CoreException {

		// try to obtain the URL of the JAR file that contains the plugin entry from teh site.xml
		// if it doesn't exist, use the default one
		URL jarURL = ((Site) getSite()).getURL(getArchiveID(pluginEntry));
		String path = UpdateManagerUtils.getPath(jarURL);					
		String[] result = getJAREntries(path);

		return result;
	}

	/**
	 * Transfer feature.jar file locally
	 */
	private void transferLocally() throws CoreException {
		// install in DEFAULT PATH for feature
		// as we OWN the temp site

		try {
			String path = UpdateManagerUtils.getPath(getURL());			
			URL resolvedURL = UpdateManagerUtils.resolveAsLocal(getURL(),path,null);
			this.setURL(resolvedURL);

			// DEBUG:
			if (UpdateManagerPlugin.DEBUG && UpdateManagerPlugin.DEBUG_SHOW_INSTALL) {
				UpdateManagerPlugin.getPlugin().debug("the feature on TEMP file is :" + resolvedURL.toExternalForm());
			}
		} catch (IOException e) {
			String id = UpdateManagerPlugin.getPlugin().getDescriptor().getUniqueIdentifier();
			IStatus status = new Status(IStatus.ERROR, id, IStatus.OK, "Error transfering feature to TEMP directory", e);
			throw new CoreException(status);
		}
	}

	/**
	 * return the archive ID for a plugin
	 */
	private String getArchiveID(IPluginEntry entry) {
		return Site.DEFAULT_PLUGIN_PATH+entry.getIdentifier().toString() + JAR_EXTENSION;
	}

	/**
	 * @see AbstractFeature#getContentReferences()
	 */
	public String[] getArchives() {
		String[] names = new String[getPluginEntryCount()];
		IPluginEntry[] entries = getPluginEntries();
		for (int i = 0; i < getPluginEntryCount(); i++) {
			names[i] = getArchiveID(entries[i]);
		}
		return names;
	}

	/**
	 * @see AbstractFeature#isInstallable()
	 */
	public boolean isInstallable() {
		return true;
	}

	/**
	 * @see AbstractFeature#getInputStreamFor(String)
	 */
	protected InputStream getInputStreamFor(String name) throws CoreException, IOException {
		URL siteURL = getSite().getURL();
		InputStream result = null;
		try {
			// ensure the file is local
			transferLocally();

			// teh feature must have a URL as 
			//it has been transfered locally
			String filePath = UpdateManagerUtils.getPath(getURL());						
			if (!(new File(filePath)).exists())
				throw new IOException("The File:" + filePath + "does not exist.");
			open(filePath);
			ZipEntry entry = currentOpenJarFile.getEntry(name);
			result = currentOpenJarFile.getInputStream(entry);

		} catch (IOException e) {
			throw new IOException("Error opening :" + name + " in feature archive:" + getURL().toExternalForm() + "\r\n" + e.toString());
		}
		return result;
	}

	/**
	 * @see AbstractFeature#getStorageUnitNames()
	 */
	protected String[] getStorageUnitNames() throws CoreException {

		// make sure the feature archive has been transfered locally
		transferLocally();

		// get the URL of the feature JAR file 
		// must exist as we tranfered it locally
		String path = UpdateManagerUtils.getPath(getURL());					
		String[] result = getJAREntries(path);

		return result;
	}

	/**
	 * return the list of entries in the JAR file
	 * Do not retrun Directory entries
	 * 
	 * do not get directories only entry as the directories will
	 * be created when teh fils will be created
	 * it was difficult to obtain a correct URL for a Directory inside a JAR
	 * because of the last '\' in the entry
	 */
	private String[] getJAREntries(String path) throws CoreException {
		String[] result = new String[0];
		try {
			JarFile jarFile = new JarFile(path);
			List list = new ArrayList();
			Enumeration enum = jarFile.entries();
			int loop = 0;
			while (enum.hasMoreElements()) {
				ZipEntry nextEntry = (ZipEntry) enum.nextElement();
				if (!nextEntry.isDirectory()) {
					list.add(nextEntry.getName());
					loop++;
				}
			}
			jarFile.close();

			// set the result			
			if (loop > 0 && !list.isEmpty()) {
				result = new String[loop];
				list.toArray(result);
			}
		} catch (IOException e) {
			String id = UpdateManagerPlugin.getPlugin().getDescriptor().getUniqueIdentifier();
			IStatus status = new Status(IStatus.ERROR, id, IStatus.OK, "Error opening JAR file:" + path, e);
			throw new CoreException(status);
		}
		return result;
	}

	/**
	 * @see AbstractFeature#close(IPluginEntry)
	 */
	protected void close(IPluginEntry entry) throws IOException {
		if (currentOpenJarFile != null)
			currentOpenJarFile.close();
	}

	/**
	 * @see AbstractFeature#closeFeature()
	 */
	public void closeFeature() throws IOException {
		if (currentOpenJarFile != null)
			currentOpenJarFile.close();
	}

	/**
	 * opens a JAR file or returns the one already opened 
	 * if teh path is the same.
	 */
	protected void open(String filePath) throws IOException {
		JarFile newJarFile = new JarFile(filePath);
		open(newJarFile);
	}

	/**
	 * opens a JAR file or returns the one already opened
	 * if teh path is the same.
	 */
	protected void open(JarFile newJarFile) throws IOException {

		// are we looking into teh same Jar file
		// or shoudl we close the previously opened one and open another one ?
		if (currentOpenJarFile != null) {
			if (!currentOpenJarFile.getName().equals(newJarFile.getName())) {
				currentOpenJarFile.close();
				currentOpenJarFile = newJarFile;
			} else {
				newJarFile.close();
			}
		} else {
			currentOpenJarFile = newJarFile;
		}
	}

	/**
	 * return the appropriate resource bundle for this feature
	 * Need to override as opening the JAR keeps it locked
	 * 
	 * baseclass + "_" + language1 + "_" + country1 + "_" + variant1 
	 * baseclass + "_" + language1 + "_" + country1 + "_" + variant1 + ".properties" 
	 * baseclass + "_" + language1 + "_" + country1 
	 * baseclass + "_" + language1 + "_" + country1 + ".properties" 
	 * baseclass + "_" + language1 
	 * baseclass + "_" + language1 + ".properties" 
	 * baseclass + "_" + language2 + "_" + country2 + "_" + variant2 
	 * baseclass + "_" + language2 + "_" + country2 + "_" + variant2 + ".properties" 
	 * baseclass + "_" + language2 + "_" + country2 
	 * baseclass + "_" + language2 + "_" + country2 + ".properties" 
	 * baseclass + "_" + language2 
	 * baseclass + "_" + language2 + ".properties" 
	 * baseclass 
	 * baseclass + ".properties" 
	 */
	public ResourceBundle getResourceBundle() throws IOException, CoreException {

		ResourceBundle result = null;
		String[] names = getStorageUnitNames();
		String base = FEATURE_FILE;

		// retrive names in teh JAR that starts with the basename
		// remove FEATURE_XML file
		List baseNames = new ArrayList();
		for (int i = 0; i < names.length; i++) {
			if (names[i].startsWith(base))
				baseNames.add(names[i]);
		}
		baseNames.remove(FEATURE_XML);

		// is there any file		
		if (!baseNames.isEmpty()) {

			Locale locale = Locale.getDefault();
			String lang1 = locale.getLanguage();
			String country1 = locale.getCountry();
			String variant1 = locale.getVariant();
			String[] attempt =
				new String[] {
					base + "_" + lang1 + "_" + country1 + "_" + variant1,
					base + "_" + lang1 + "_" + country1 + "_" + variant1 + ".properties",
					base + "_" + lang1 + "_" + country1,
					base + "_" + lang1 + "_" + country1 + ".properties",
					base + "_" + lang1,
					base + "_" + lang1 + ".properties",
					base,
					base + ".properties" };

			boolean found = false;
			int index = 0;
			while (!found && index < attempt.length) {
				if (baseNames.contains(attempt[index])) {
					result = new PropertyResourceBundle(getInputStreamFor(attempt[index]));
					found = true;
				}
				index++;
			}

		} // baseNames is empty

		if (result == null) {
			if (UpdateManagerPlugin.DEBUG && UpdateManagerPlugin.DEBUG_SHOW_WARNINGS) {
				UpdateManagerPlugin.getPlugin().debug("Cannot find resourceBundle for:" + base + " - " + Locale.getDefault().toString() + ":" + this.getURL().toExternalForm());
			}
		}
		return result;
	}
}