/*******************************************************************************

* Copyright (c) 2007 IONA Technologies PLC

* 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:

*     IONA Technologies PLC - initial API and implementation

*******************************************************************************/
package org.eclipse.stp.sc.common.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;

/**
 * @author jma
 *
 */
public class JarUtils {
	
	public static String PATH_SEPERATOR = "/";
	
	public static JarOutputStream createJarOutputStream(String filePath) throws IOException {
		return createJarOutputStream(filePath, null);
	}
	
	public static JarOutputStream createJarOutputStream(String filePath, String manifestPath)
	    throws IOException {
		File targetFile = new File(filePath);
		FileOutputStream fos = new FileOutputStream(targetFile);
		if (manifestPath == null) {
			return new JarOutputStream(fos, new Manifest());
		}
		FileInputStream fis = new FileInputStream(manifestPath);
		return new JarOutputStream(fos, new Manifest(fis));
	}
	
	public static void addOneTargetDir(JarOutputStream output, IFolder folderToAdd, String targetPath)
    throws CoreException, IOException {
		
		if(folderToAdd != null && folderToAdd.exists()){
			for (IResource member : folderToAdd.members()) {
				if (member.getType() == IResource.FOLDER) {
					String filePath = targetPath;
					if (!filePath.equals("")) {
							if (!filePath.endsWith(PATH_SEPERATOR)) {
								filePath += PATH_SEPERATOR;
							}
					}
					filePath = filePath + member.getName();
					addOneTargetDir(output, (IFolder)member, filePath);
					continue;
				}
				if (member.getType() != IResource.FILE){
					continue;
				}
				
				String targetName = member.getName();
				if(!targetPath.trim().equals("")){
					targetName = targetPath + PATH_SEPERATOR + member.getName();
				}
				addToJar(output, targetName, (IFile)member);
			}			
		}
	}
	
	public static void addToJar(JarOutputStream output, String fileName, IFile targetFile) throws IOException {
        addToJar(output, fileName, targetFile.getRawLocation().toOSString());	
    }
    
    public static void addToJar(JarOutputStream output, String fileName, String filePath) throws IOException {
    	JarEntry jarAdd = new JarEntry(fileName);
    	File file = new File(filePath);
    	jarAdd.setTime(file.lastModified());
        output.putNextEntry(jarAdd);
        FileInputStream in = new FileInputStream(file);
        byte buffer[] = new byte[10240];
        int read = 0;
        while ((read = in.read(buffer, 0, buffer.length)) > 0) {
          output.write(buffer, 0, read);
        }
        in.close();
    }
    

    public static boolean unJarFile(String jarFileName, String outputDirectory) throws Exception {
		JarInputStream in = null;		
		try {
			File target = new File(outputDirectory);
			if(!target.exists()){
				target.mkdir();
			}
			in = new JarInputStream(new FileInputStream(jarFileName));
			JarEntry jen;
			//write manifest
			if(in.getManifest() != null){
				File manifest = new File(outputDirectory + File.separator
						+ "MATA-INF" + File.separator + "MANIFEST.MF");
				if(!manifest.getParentFile().exists()){
					createFolder(manifest.getParentFile()); 
				}
				manifest.createNewFile();
				FileOutputStream out = new FileOutputStream(manifest);
				in.getManifest().write(out);
				out.close();
			}

			while ((jen = in.getNextJarEntry()) != null) {
				if (jen.isDirectory()) {
					String name = jen.getName();
					name = name.substring(0, name.length() - 1);
					File file = new File(outputDirectory + File.separator
							+ name);
					file.mkdir();
				} else {
					String fname = outputDirectory
							+ File.separator
							+ jen.getName().substring(0,
									jen.getName().indexOf("/"));
					File dt = new File(fname);
					if (!dt.exists()) {
						dt.mkdir();
					}
					File file = new File(outputDirectory + File.separator
							+ jen.getName());
					
					creatFileForJarEntry(file, in);					
					
				}
			}
			in.close();
			return true;
		} finally{
			if(in != null){
				in.close();
			}
		}
		
	}   
    private static void creatFileForJarEntry(File file, JarInputStream in) throws Exception{
    	if(!file.getParentFile().exists()){
			createFolder(file.getParentFile());
		}
		file.createNewFile();
		FileOutputStream out = new FileOutputStream(file);
		int b;
		while ((b = in.read()) != -1) {
			out.write(b);
		}
		out.close();
		
    }
    public static boolean createFolder(File file){    	
    	
    	if(!file.getParentFile().exists()){
    		createFolder(file.getParentFile());
    	}
    	if(!file.exists()){
    		file.mkdir();
    	}
    	return true;
    }
}
