/*******************************************************************************
 * Copyright (c) 2000, 2006 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.jdt.ui.jarpackager;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.OperationCanceledException;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.swt.widgets.Shell;

import org.eclipse.jface.util.Assert;

import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.jarpackager.JarPackagerMessages;
import org.eclipse.jdt.internal.ui.jarpackager.JarPackagerUtil;

/**
 * Creates a JAR file for the given JAR package data.
 * <p>
 * Clients may subclass.
 * </p>
 * 
 * @see org.eclipse.jdt.ui.jarpackager.JarPackageData
 * @since 3.1
 * 
 * @deprecated Use JarWriter3 instead which leverages new {@link org.eclipse.core.filesystem.EFS EFS} support
 */
public class JarWriter2 {
	
	private JarOutputStream fJarOutputStream;
	private JarPackageData fJarPackage;

	private Set fDirectories= new HashSet();
	
	/**
	 * Creates an instance which is used to create a JAR based
	 * on the given JarPackage.
	 *
	 * @param jarPackage		the JAR specification
	 * @param parent			the shell used to display question dialogs,
	 *				 			or <code>null</code> if "false/no/cancel" is the answer
	 * 							and no dialog should be shown
	 * @throws	CoreException	to signal any other unusual termination.
	 * 							This can also be used to return information
	 * 							in the status object.
	 */
	public JarWriter2(JarPackageData jarPackage, Shell parent) throws CoreException {
		Assert.isNotNull(jarPackage, "The JAR specification is null"); //$NON-NLS-1$
		fJarPackage= jarPackage;
		Assert.isTrue(fJarPackage.isValid(), "The JAR package specification is invalid"); //$NON-NLS-1$
		if (!canCreateJar(parent))
			throw new OperationCanceledException();

		try {
			if (fJarPackage.usesManifest() && fJarPackage.areGeneratedFilesExported()) {
				Manifest manifest=  fJarPackage.getManifestProvider().create(fJarPackage);
				fJarOutputStream= new JarOutputStream(new FileOutputStream(fJarPackage.getAbsoluteJarLocation().toOSString()), manifest);
			} else
				fJarOutputStream= new JarOutputStream(new FileOutputStream(fJarPackage.getAbsoluteJarLocation().toOSString()));
			String comment= jarPackage.getComment();
			if (comment != null)
				fJarOutputStream.setComment(comment);
		} catch (IOException ex) {
			throw JarPackagerUtil.createCoreException(ex.getLocalizedMessage(), ex);
		}
	}
	
	/**
	 * Closes the archive and does all required cleanup.
	 *
	 * @throws	CoreException	to signal any other unusual termination.
	 * 								This can also be used to return information
	 * 								in the status object.
	 */
	public void close() throws CoreException {
		if (fJarOutputStream != null)
			try {
				fJarOutputStream.close();
				registerInWorkspaceIfNeeded();
			} catch (IOException ex) {
				throw JarPackagerUtil.createCoreException(ex.getLocalizedMessage(), ex);
			}
	}
	
	/**
	 * Writes the passed resource to the current archive.
	 *
	 * @param resource			the file to be written
	 * @param destinationPath	the path for the file inside the archive
	 * @throws	CoreException	to signal any other unusual termination.
	 * 								This can also be used to return information
	 * 								in the status object.
	 */
	public void write(IFile resource, IPath destinationPath) throws CoreException {
		try {
			IPath fileLocation= resource.getLocation();
			File file= null;
			if (fileLocation != null) {
				file= new File(fileLocation.toOSString());
			}
			if (fJarPackage.areDirectoryEntriesIncluded())
				addDirectories(destinationPath, file);
			addFile(resource, destinationPath, file);
		} catch (IOException ex) {
			// Ensure full path is visible
			String message= null;
			if (ex.getLocalizedMessage() != null)
				message= Messages.format(JarPackagerMessages.JarWriter_writeProblemWithMessage, new Object[] {resource.getFullPath(), ex.getLocalizedMessage()}); 
			else
				message= Messages.format(JarPackagerMessages.JarWriter_writeProblem, resource.getFullPath()); 
			throw JarPackagerUtil.createCoreException(message, ex);
		}					
	}
	
	/**
	 * Creates a new JarEntry with the passed path and contents, and writes it
	 * to the current archive.
	 *
	 * @param	resource			the file to write
	 * @param	path				the path inside the archive
	 * @param	correspondingFile	the corresponding file in the file system
	 *								or <code>null</code> if it doesn't exist
     * @throws	IOException			if an I/O error has occurred
	 * @throws	CoreException 		if the resource can-t be accessed
	 */
	protected void addFile(IFile resource, IPath path, File correspondingFile) throws IOException, CoreException {
		JarEntry newEntry= new JarEntry(path.toString().replace(File.separatorChar, '/'));
		byte[] readBuffer= new byte[4096];             

		if (fJarPackage.isCompressed())
			newEntry.setMethod(ZipEntry.DEFLATED);
			// Entry is filled automatically.
		else {
			newEntry.setMethod(ZipEntry.STORED);
			calculateCrcAndSize(newEntry, resource, readBuffer);
		}

		long lastModified= correspondingFile != null && correspondingFile.exists() ? correspondingFile.lastModified() : System.currentTimeMillis();
		// Set modification time
		newEntry.setTime(lastModified);

		InputStream contentStream = resource.getContents(false);

		try {		
			fJarOutputStream.putNextEntry(newEntry);
			int count;
			while ((count= contentStream.read(readBuffer, 0, readBuffer.length)) != -1)
				fJarOutputStream.write(readBuffer, 0, count);
		} finally  {
			if (contentStream != null)
				contentStream.close();

			/*
			 * Commented out because some JREs throw an NPE if a stream
			 * is closed twice. This works because
			 * a) putNextEntry closes the previous entry
			 * b) closing the stream closes the last entry
			 */
			// fJarOutputStream.closeEntry();
		}
	}

	/**
	 * Calculates the CRC and size of the resource and updates the jarEntry.
	 * 
	 * @param jarEntry			the JarEntry to update
	 * @param resource			the file to calculate 
	 * @param readBuffer 		a shared read buffer to store temporary data
	 * 
     * @throws	IOException		if an I/O error has occurred
	 * @throws	CoreException 	if the resource can-t be accessed
	 */
	private void calculateCrcAndSize(JarEntry jarEntry, IFile resource, byte[] readBuffer) throws IOException, CoreException {
		InputStream contentStream = resource.getContents(false);
		int size = 0;
		CRC32 checksumCalculator= new CRC32();
		int count;
		try {
			while ((count= contentStream.read(readBuffer, 0, readBuffer.length)) != -1) {
				checksumCalculator.update(readBuffer, 0, count);
				size += count;
			}
		} finally {
			if (contentStream != null)
				contentStream.close();
		}
		jarEntry.setSize(size);
		jarEntry.setCrc(checksumCalculator.getValue());
	}
	
	/**
	 * Creates the directory entries for the given path and writes it to the 
	 * current archive.
	 * 
	 * @param destinationPath 	the path to add
	 * @param correspondingFile the corresponding file in the file system 
	 *  						or <code>null</code> if it doesn't exist
	 * @throws IOException if an I/O error has occurred  
	 */
	protected void addDirectories(IPath destinationPath, File correspondingFile) throws IOException {
		String path= destinationPath.toString().replace(File.separatorChar, '/');
		int lastSlash= path.lastIndexOf('/');
		List directories= new ArrayList(2);
		while(lastSlash != -1) {
			path= path.substring(0, lastSlash + 1);
			if (!fDirectories.add(path))
				break;

			if (correspondingFile != null)
				correspondingFile= correspondingFile.getParentFile();
			long timeStamp= correspondingFile != null && correspondingFile.exists() 
				? correspondingFile.lastModified() 
				: System.currentTimeMillis();
				
			JarEntry newEntry= new JarEntry(path);
			newEntry.setMethod(ZipEntry.STORED);
			newEntry.setSize(0);
			newEntry.setCrc(0);
			newEntry.setTime(timeStamp);
			directories.add(newEntry);
			
			lastSlash= path.lastIndexOf('/', lastSlash - 1);
		}
			
		for(int i= directories.size() - 1; i >= 0; --i) {
			fJarOutputStream.putNextEntry((JarEntry)directories.get(i));
		}
	}

	/**
	 * Checks if the JAR file can be overwritten.
	 * If the JAR package setting does not allow to overwrite the JAR
	 * then a dialog will ask the user again.
	 * 
	 * @param	parent	the parent for the dialog,
	 * 			or <code>null</code> if no dialog should be presented
	 * @return	<code>true</code> if it is OK to create the JAR
	 */
	protected boolean canCreateJar(Shell parent) {
		File file= fJarPackage.getAbsoluteJarLocation().toFile();
		if (file.exists()) {
			if (!file.canWrite())
				return false;
			if (fJarPackage.allowOverwrite())
				return true;
			return parent != null && JarPackagerUtil.askForOverwritePermission(parent, fJarPackage.getAbsoluteJarLocation().toOSString());
		}
					
		// Test if directory exists
		String path= file.getAbsolutePath();
		int separatorIndex = path.lastIndexOf(File.separator);
		if (separatorIndex == -1) // i.e.- default directory, which is fine
			return true;
		File directory= new File(path.substring(0, separatorIndex));
		if (!directory.exists()) {
			if (JarPackagerUtil.askToCreateDirectory(parent, directory))
				return directory.mkdirs();
			else
				return false;
		}
		return true;
	}

	private void registerInWorkspaceIfNeeded() {
		IPath jarPath= fJarPackage.getAbsoluteJarLocation();
		IProject[] projects= ResourcesPlugin.getWorkspace().getRoot().getProjects();
		for (int i= 0; i < projects.length; i++) {
			IProject project= projects[i];
			// The Jar is always put into the local file system. So it can only be
			// part of a project if the project is local as well. So using getLocation
			// is currently save here.
			IPath projectLocation= project.getLocation();
			if (projectLocation != null && projectLocation.isPrefixOf(jarPath)) {
				try {
					jarPath= jarPath.removeFirstSegments(projectLocation.segmentCount());
					jarPath= jarPath.removeLastSegments(1);
					IResource containingFolder= project.findMember(jarPath);
					if (containingFolder != null && containingFolder.isAccessible())
						containingFolder.refreshLocal(IResource.DEPTH_ONE, null);
				} catch (CoreException ex) {
					// don't refresh the folder but log the problem
					JavaPlugin.log(ex);
				}
			}
		}
	}
}
