/*******************************************************************************
 * Copyright (c) 2005, 2007 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.jst.jee.archive.internal;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.eclipse.jst.jee.archive.ArchiveSaveFailureException;


public class ArchiveUtil {
	
	protected static String tempDirectoryName;

	protected static java.io.File tempDirectory;

	/**
	 * Returns the filename from the uri, or the segment after the last
	 * occurrence of a separator
	 */
	public static String getFileNameTail(String uri) {
		String tempURI = uri.replace('\\', '/');
		while (tempURI.endsWith("/")) //$NON-NLS-1$
			tempURI = tempURI.substring(0, tempURI.length() - 1);
		int lastIndex = tempURI.lastIndexOf('/');
		if (lastIndex == -1)
			return uri;
		return uri.substring(lastIndex + 1, tempURI.length());
	}

	public static java.io.File getTempDirectory() {
		return tempDirectory;
	}

	public static java.io.File createTempFile(String baseName) throws IOException {
		return createTempFile(baseName, getTempDirectory());
	}

	public static java.io.File createTempFile(String baseName, java.io.File directory) throws IOException {
		String fileName = getFileNameTail(baseName);
		if (fileName.length() < 3) {
			fileName = "WSTMP" + fileName; //$NON-NLS-1$
		}
		java.io.File tempFile = java.io.File.createTempFile(fileName, null, directory);
		DeleteOnExitUtility.markForDeletion(tempFile);
		return tempFile;
	}

	/**
	 * returns a list of all files, recursive, that can't be written
	 */
	public static List getWriteProtectedFiles(java.io.File aFile, List aList) {
		if (aList == null)
			aList = new ArrayList();
		if (aFile.exists() && !aFile.canWrite())
			aList.add(aFile);
		if (aFile.isDirectory()) {
			java.io.File[] files = aFile.listFiles();
			for (int i = 0; i < files.length; i++) {
				getWriteProtectedFiles(files[i], aList);
			}
		}
		return aList;
	}

	public static void checkWriteable(java.io.File aFile) throws ArchiveSaveFailureException {
		List locked = ArchiveUtil.getWriteProtectedFiles(aFile, null);
		if (locked.isEmpty())
			return;

		StringBuffer msg = new StringBuffer();
		msg.append("Cannot write to file: "); //$NON-NLS-1$
		msg.append(aFile.getAbsolutePath());
		msg.append('\n');
		msg.append("One or more files is write protected or locked:"); //$NON-NLS-1$
		msg.append('\n');
		for (int i = 0; i < locked.size(); i++) {
			java.io.File lockedFile = (java.io.File) locked.get(i);
			msg.append(lockedFile.getAbsolutePath());
			msg.append('\n');
		}
		throw new ArchiveSaveFailureException(msg.toString());
	}

	/**
	 * deletes a file from the file system; for directories, recurse the
	 * subdirectories and delete them as well
	 * 
	 * @return true if successful; false if any file or sub file could not be
	 *         deleted
	 */
	public static boolean delete(java.io.File aFile) {
		if (aFile == null)
			return true;
		if (aFile.isDirectory()) {
			java.io.File[] files = aFile.listFiles();
			if (files != null) {
				for (int i = 0; i < files.length; i++) {
					if (!delete(files[i]))
						return false;
				}
			}
		}
		return aFile.delete();
	}

	/**
	 * If we can rename it then we can delete it
	 */
	public static boolean isRenameable(java.io.File orig) {
		java.io.File origCopy1 = null;
		java.io.File origCopy2 = null;
		try {
			origCopy1 = orig.getCanonicalFile();
			origCopy2 = orig.getCanonicalFile();
		} catch (java.io.IOException ex) {
			return false;
		}
		String name = null;
		String baseName = "save.tmp"; //$NON-NLS-1$
		try {
			if (orig.getParent() != null)
				baseName = new java.io.File(orig.getParent(), baseName).getCanonicalPath();
		} catch (java.io.IOException ex) {
			return false;
		}

		java.io.File temp = null;
		int index = 0;
		do {
			name = baseName + index;
			temp = new java.io.File(name);
			index++;
		} while (temp.exists());
		return origCopy1.renameTo(temp) && temp.renameTo(origCopy2);
	}

	public static void cleanupAfterTempSave(String aUri, java.io.File original, java.io.File destinationFile) throws ArchiveSaveFailureException {

		checkWriteable(original);
		boolean deleteWorked = false;
		if (original.isDirectory() && !isRenameable(original)) {
			// TODO throw new
			// SaveFailureException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.unable_replace_EXC_,
			// (new Object[]{original.getAbsolutePath()}))); // = "Unable to
			// replace original archive "
		}

		for (int i = 0; i < 10; i++) {
			if (ArchiveUtil.delete(original)) {
				deleteWorked = true;
				break;
			}
			try {
				// TODO Major hack here; the problem is that a previous call
				// to close the source file may not yet have
				// been reflected in the os/vm; therefore a subsequent call
				// to delete fails. To get around this,
				// wait for a bit and retry; if it continues to fail, then
				// time out and throw an exception
				Thread.sleep(250);
			} catch (InterruptedException e) {
				// Ignore
			}
		}
		if (deleteWorked) {
			for (int i = 0; i < 10; i++) {
				if (destinationFile.renameTo(original)){
					DeleteOnExitUtility.fileHasBeenDeleted(destinationFile);
					return;
				}
				try {
					Thread.sleep(250);
				} catch (InterruptedException e) {
					// Ignore
				}
			}
		}
		// TODO throw new
		// SaveFailureException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.unable_replace_EXC_,
		// (new Object[]{original.getAbsolutePath()}))); // = "Unable to replace
		// original archive "
	}

	/**
	 * Copy all the data from the input stream to the output stream up until the
	 * first end of file character, and close the two streams
	 */
	public static void copy(InputStream in, OutputStream out) throws IOException {
		byte[] buffer = new byte[1024];
		try {
			int n = in.read(buffer);
			while (n > 0) {
				out.write(buffer, 0, n);
				n = in.read(buffer);
			}
		} finally {
			if (!(in instanceof ZipInputStream))
				in.close();
			if (!(out instanceof ZipOutputStream))
				out.close();
		}
	}
	
	public static void warn(Throwable e){
		org.eclipse.jem.util.logger.proxy.Logger.getLogger().logWarning(e);
	}
	
	public static void warn(String message) {
		org.eclipse.jem.util.logger.proxy.Logger.getLogger().logWarning(message);
	}
}
