/*******************************************************************************
 * Copyright (c) 2001, 2010 IBM Corporation, Red Hat, 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.jst.common.internal.modulecore.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jem.util.emf.workbench.WorkbenchByteArrayOutputStream;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;

import com.ibm.icu.util.StringTokenizer;

public class ManifestUtilities {
	public static final String MANIFEST_HEADER = "Manifest-Version: 1.0\r\nClass-Path: \r\n\r\n"; //$NON-NLS-1$
	public static void createManifestFile(IFile file) throws CoreException, IOException {
		try {
			WorkbenchByteArrayOutputStream out = new WorkbenchByteArrayOutputStream(file);
			out.write(MANIFEST_HEADER.getBytes());
			out.close();
		} catch (IOException ioe) {
			throw ioe;
		}
	}
	
	public static String[] getTokens(String aString) {
		return getTokens(aString, null);
	}

	public static String[] getTokens(String aString, String delimiter) {
		StringTokenizer tok = (delimiter == null) ? new StringTokenizer(aString) : new StringTokenizer(aString, delimiter);
		int size = tok.countTokens();
		String[] tokens = new String[size];
		for (int i = 0; i < size && tok.hasMoreTokens(); i++) {
			tokens[i] = tok.nextToken();
		}
		return tokens;
	}

	/**
	 * getValueIgnoreKeyCase method comment.
	 */
	public static java.lang.String getValueIgnoreKeyCase(java.lang.String key, java.util.jar.Attributes attr) {
		Iterator keysAndValues = attr.entrySet().iterator();
		while (keysAndValues.hasNext()) {
			Map.Entry entry = (Map.Entry) keysAndValues.next();
			String entryKey = entry.getKey().toString();
			if (entryKey.equalsIgnoreCase(key))
				return entry.getValue() == null ? null : entry.getValue().toString();
		}
		return null;
	}

	public static ArchiveManifest getManifest(IVirtualComponent component, IPath manifestPath) {
		if( !component.isBinary() )
			return getNonBinaryComponentManifest(component, manifestPath);
		return getBinaryComponentManifest(component, manifestPath);
	}
	
	public static ArchiveManifest getBinaryComponentManifest(IVirtualComponent component, IPath manifestPath) {
		java.io.File file = (File)component.getAdapter(File.class);
		if( file != null && file.exists()) {
			ArchiveManifest manifest = readBinaryManifest(file, manifestPath);
			return manifest;
		}
		return null;
	}

	public static ArchiveManifest getManifest(IFile f) {
		File f2 = f.getLocation().toFile();
		return getManifest(f2);
	}
	
	public static ArchiveManifest getManifest(File f) {
		if( f != null && f.exists()) {
				InputStream in;
				try {
					in = new FileInputStream(f);
					ArchiveManifest manifest = new ArchiveManifestImpl(in);
					return manifest;
				} catch (FileNotFoundException e) {
				} catch (IOException e) {
				}
		}
		return null;
	}
	
	public static void writeManifest(IFile aFile, ArchiveManifest manifest) throws java.io.IOException {
		OutputStream out = new WorkbenchByteArrayOutputStream(aFile);
		manifest.writeSplittingClasspath(out);
		out.close();
	}

	
	public static ArchiveManifest getNonBinaryComponentManifest(IVirtualComponent component, IPath manifestPath) {
		try {
			if(!component.isBinary()){
				IVirtualFile vManifest = component.getRootFolder().getFile(manifestPath);
				if (vManifest.exists()) {
					IFile manifestFile = vManifest.getUnderlyingFile();
					InputStream in = null;
					try {
						in = manifestFile.getContents();
						ArchiveManifest manifest = new ArchiveManifestImpl(in);
						return manifest;
					} finally {
						if (in != null) {
							in.close();
							in = null;
						}
					}
				}
			} 
		} catch( IOException ioe ) {
		} catch(CoreException ce) {
		}
		return null;
	}
	
	
	public static String[] getManifestClasspath(IVirtualComponent component, IPath manifestPath)  {
		ArchiveManifest mf = getManifest(component, manifestPath);
		if( mf != null ) 
			return mf.getClassPathTokenized();
		return new String[]{};
	}
	
	public static ArchiveManifest readBinaryManifest(File file, IPath manifestPath) {
		ArchiveManifest manifest = null;
		ZipFile zipFile = null;
		if( file != null ) {
			try {
				zipFile = ManifestUtilities.newZipFile(file);
				ZipEntry entry = zipFile.getEntry(manifestPath.toString());
				if( entry != null ) {
					InputStream entryStream = getInputstreamForZipEntry(zipFile, manifestPath.toString());
					manifest = new ArchiveManifestImpl(entryStream);
					zipFile.close();
				}
			} catch( IOException ioe) {
				if( zipFile != null ) {
					try {
						zipFile.close();
					} catch( IOException ioe2) {}
				}
			}
		}
		return manifest;
	}
	
	public static InputStream getInputstreamForZipEntry(ZipFile zipFile, String uri) throws IOException {
		try {
			ZipEntry entry = zipFile.getEntry(uri);
			if (entry == null) {
				// this is a hack, but zip files are sensitive to the difference
				// between '/' and '\\'
				// so the hack is to try all combinations to see if any exist
				char[] chars = uri.toCharArray();
				int[] slashIndices = new int[chars.length];
				int slashCount = 0;
				for (int i = 0; i < uri.length(); i++) {
					if (chars[i] == '/' || chars[i] == '\\') {
						slashIndices[slashCount] = i;
						slashCount++;
					}
				}
				int slashPow = (int) Math.pow(2, slashCount);
				boolean foundIt = false;
				for (int i = 0; i < slashPow && !foundIt; i++) {
					for (int j = 0; j < slashCount; j++) {
						if ((i >> j & 1) == 1) {
							chars[slashIndices[j]] = '/';
						} else {
							chars[slashIndices[j]] = '\\';
						}
					}
					entry = zipFile.getEntry(new String(chars));
					if (entry != null) {
						foundIt = true;
					}
				}
				if (entry == null) {
					Exception del = new FileNotFoundException(uri);
					throw new IOException(del.toString());
				}
			}
			return new java.io.BufferedInputStream(zipFile.getInputStream(entry));
		} catch (IllegalStateException zipClosed) {
			throw new IOException(zipClosed.toString());
		}
	}
	
	public static String[] getNonBinaryComponentManifestClasspath(IVirtualComponent component, IPath manifestPath)
			throws IOException, CoreException {
		String[] manifestClasspath = null;
		if(!component.isBinary()){
			IVirtualFile vManifest = component.getRootFolder().getFile(manifestPath);
			if (vManifest.exists()) {
				IFile manifestFile = vManifest.getUnderlyingFile();
				InputStream in = null;
				try {
					in = manifestFile.getContents();
					ArchiveManifest manifest = new ArchiveManifestImpl(in);
					manifestClasspath = manifest.getClassPathTokenized();
				} finally {
					if (in != null) {
						in.close();
						in = null;
					}
				}
			}
		} 
		return manifestClasspath;
	}

	public static ZipFile newZipFile(String fileName)throws ZipException, IOException {
		return ManifestUtilities.newZipFile(new File(fileName), ZipFile.OPEN_READ);
	}
	public static ZipFile newZipFile(File aFile)throws ZipException, IOException {
		return ManifestUtilities.newZipFile(aFile, ZipFile.OPEN_READ);
	}
	
	/**
	 * Utility to create ZipFiles which avoid memory leaks 
	 * because closing them fails to close open inputstreams.
	 * There is a SUN bug open for this: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6735255 
     * but it looks like the "fix" will be to change the Javadoc :-(   
	 * @param aFile mode
	 * @return
	 * @throws ZipException
	 * @throws IOException
	 */
	public static ZipFile newZipFile(File aFile, int mode) throws ZipException, IOException {
		return new ZipFile(aFile, mode){
			Collection <InputStream> openStreams = null;
			
			@Override
			public InputStream getInputStream(ZipEntry entry) throws IOException {
				InputStream in = super.getInputStream(entry);
				if(in != null){
					if(openStreams == null){
						openStreams = new ArrayList<InputStream>();
					}
					openStreams.add(in);
				}
				return in;
			}
			
			@Override
			public void close() throws IOException {
				closeOpenStreams();
				super.close();
			}

			private void closeOpenStreams() {
				if(openStreams != null){
					for (Iterator iterator = openStreams.iterator(); iterator.hasNext();) {
						InputStream in = (InputStream) iterator.next();
						try {
							in.close();
						} catch (IOException e) {
							org.eclipse.jem.util.logger.proxy.Logger.getLogger().logWarning(e);
						}
						iterator.remove();
					}
				}
			}
		};
	}
	
	public static ArchiveManifest readManifest(IFile aFile) {
		InputStream in = null;
		try {
			if (aFile == null || !aFile.exists())
				return null;
			in = aFile.getContents();
			return new ArchiveManifestImpl(in);
		} catch (Exception ex) {
			// TODO J2EEPlugin.logError(ex);
			return null;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException weTried) {
				}
			}
		}
	}

	/**
	 * Generates new MANIFEST.MF with a dynamically updated classpath that is written to the specified
	 * output stream.
	 * @param manifestFile The current MANIFEST.MF file.
	 * @param dynamicURIs Is List of URIs to dynamically add to the manifest classpath.
	 * @param outputStream Stream to which the modified entry should be written.
	 * @throws IOException
	 * @throws FileNotFoundException
	 */
	public static void updateManifestClasspath(final IFile manifestFile, final List dynamicURIs, final OutputStream outputStream) throws IOException, FileNotFoundException {
		updateManifestClasspathImpl(manifestFile, dynamicURIs, null, outputStream);
    }
	
	/**
	 * Generates new MANIFEST.MF with a dynamically updated classpath that is written to the specified
	 * output stream.
	 * @param manifestFile The current MANIFEST.MF file.
	 * @param dynamicURIs Is List of URIs to dynamically add to the manifest classpath.
	 * @param outputFile File to which the modified entry should be written.
	 * @throws IOException
	 * @throws FileNotFoundException
	 */
	public static void updateManifestClasspath(final IFile manifestFile, final List dynamicURIs, final File outputFile) throws IOException, FileNotFoundException {
		updateManifestClasspathImpl(manifestFile, dynamicURIs, outputFile, null);
    }

	/**
	 * Generates new MANIFEST.MF with a dynamically updated classpath that is written to the specified
	 * file or output stream, with the stream taking precedence.
	 * @param manifestFile The current MANIFEST.MF file.
	 * @param dynamicURIs Is List of URIs to dynamically add to the manifest classpath.
	 * @param outputFile File to which the modified entry should be written.
	 * @param OutputStream stream Stream to which the modified entry should be written. If not null,
	 * the stream will be written and the outputFile ignored.
	 * @throws IOException
	 * @throws FileNotFoundException
	 */
	private static void updateManifestClasspathImpl(final IFile manifestFile, final List dynamicURIs, final File outputFile, final OutputStream stream) throws IOException, FileNotFoundException {
		
		OutputStream outputStream = stream; 
        try {
        	InputStream in = null;
        	ArchiveManifest manifest = null;
        	try {
        		in = manifestFile.getContents();
        		manifest = new ArchiveManifestImpl(in);
        	} catch (CoreException ce) {
        		throw new IOException(ce.getLocalizedMessage());
        	} finally {
        		if (in != null) {
        			try {
        				in.close();
        				in = null;
        			} catch (IOException e) {
						org.eclipse.jem.util.logger.proxy.Logger.getLogger().logWarning(e);
        			}
        		}
        	}
        	final String[] manifestClasspath = manifest.getClassPathTokenized();
        	final List updatedCP = new ArrayList();
        	for (int i = 0; i < manifestClasspath.length; i++) {
        		updatedCP.add(manifestClasspath[i]);
        	}
        	// update manifest classpath to include dynamic entries
        	for (int j = 0; j < dynamicURIs.size(); j++) {
        		final String containerURI = (String) dynamicURIs.get(j);
        		// need to check existing entries to ensure it doesn't are exist on the classpath
        		boolean exists = false;
        		for (int i = 0; i < manifestClasspath.length; i++) {
        			if (manifestClasspath[i].equals(containerURI)) {
        				exists = true;
        				break;
        			}
        		}
        		if (!exists) {
        			updatedCP.add(containerURI);
        		}
        	}
        	final StringBuffer cpBuffer = new StringBuffer();
        	boolean first = true;
        	for (int j = 0; j < updatedCP.size(); j++) {
        		if (!first) {
        			cpBuffer.append(" "); //$NON-NLS-1$
        		} else {
        			first = false;
        		}
        		cpBuffer.append((String) updatedCP.get(j));
        	}
        	String cp = cpBuffer.toString();
        	// If we have an output stream, always write to the stream 
        	if (outputStream != null) {
            	manifest.setClassPath(cp);
            	manifest.write(outputStream);
            	outputStream.flush();
        	}
        	// Else, without an output stream, conditionally update the specified file
        	else {
            	manifest.setClassPath(cp);
            	outputStream = new FileOutputStream(outputFile);
            	manifest.write(outputStream);
            	outputStream.flush();
        	}
        } finally {
        	if (outputStream != null) {
        		outputStream.close();
        	}
        }
    }

	
}
