/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.update.core;

import java.io.*;
import java.text.*;
import java.util.*;

import org.eclipse.core.runtime.*;
import org.eclipse.update.core.model.*;
import org.eclipse.update.internal.core.*;

/**
 * This class is a collection of utility functions that can be 
 * used for install processing
 * <p>
 * <b>Note:</b> This class/interface is part of an interim API that is still under development and expected to
 * change significantly before reaching stability. It is being made available at this early stage to solicit feedback
 * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
 * (repeatedly) as the API evolves.
 * </p>
 */
public class Utilities {

	private static Map entryMap;
	private static final DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.getDefault());
	private static long tmpseed = (new Date()).getTime();
	private static String dirRoot = null;

	/**
	 * Returns a new working directory (in temporary space). Ensures
	 * the directory exists. Any directory levels that had to be created
	 * are marked for deletion on exit.
	 * 
	 * @return working directory
	 * @exception IOException
	 * @since 2.0
	 */
	public static synchronized File createWorkingDirectory() throws IOException {

		if (dirRoot == null) {
			dirRoot = System.getProperty("java.io.tmpdir"); //$NON-NLS-1$
			// in Linux, returns '/tmp', we must add '/'
			if (!dirRoot.endsWith(File.separator))
				dirRoot += File.separator;

			// on Unix/Linux, the temp dir is shared by many users, so we need to ensure 
			// that the top working directory is different for each user
			if (!Platform.getOS().equals("win32")) { //$NON-NLS-1$
				String home = System.getProperty("user.home"); //$NON-NLS-1$
				home = Integer.toString(home.hashCode());
				dirRoot += home + File.separator;
			}
			dirRoot += "eclipse" + File.separator + ".update" + File.separator + Long.toString(tmpseed) + File.separator; //$NON-NLS-1$ //$NON-NLS-2$
		}

		String tmpName = dirRoot + Long.toString(++tmpseed) + File.separator;

		File tmpDir = new File(tmpName);
		verifyPath(tmpDir, false);
		if (!tmpDir.exists())
			throw new FileNotFoundException(tmpName);
		return tmpDir;
	}

	/**
	 * Create a new working file. The file is marked for deletion on exit.
	 * 
	 * @see #lookupLocalFile(String)
	 * @param tmpDir directory location for new file. Any missing directory
	 * levels are created (and marked for deletion on exit)
	 * @param name optional file name, or <code>null</code>. If name is not
	 * specified, a temporary name is generated.
	 * @return created working file
	 * @exception IOException
	 * @since 2.0
	 */
	public static synchronized File createLocalFile(File tmpDir, String name) throws IOException {
		// create the local file
		File temp;
		String filePath;
		if (name != null) {
			// create file with specified name
			filePath = name.replace('/', File.separatorChar);
			if (filePath.startsWith(File.separator))
				filePath = filePath.substring(1);
			temp = new File(tmpDir, filePath);
		} else {
			// create file with temp name
			temp = File.createTempFile("eclipse", null, tmpDir); //$NON-NLS-1$
		}
		temp.deleteOnExit();
		verifyPath(temp, true);

		return temp;
	}

	/**
	 * The file is associated with a lookup key.
	 * @param key optional lookup key, or <code>null</code>.
	 * @param temp the local working file
	 * @since 2.0.2
	 */
	public synchronized static void mapLocalFile(String key, File temp) {
		// create file association 
		if (key != null) {
			if (entryMap == null)
				entryMap = new HashMap();
			entryMap.put(key, temp);
		}
	}

	/**
	 * Returns a previously cached local file (in temporary area) matching the
	 * specified key. 
	 * 
	 * @param key lookup key
	 * @return cached file, or <code>null</code>.
	 * @since 2.0
	 */
	public static synchronized File lookupLocalFile(String key) {
		if (entryMap == null)
			return null;
		return (File) entryMap.get(key);
	}

	/**
	 * Flushes all the keys from the local file map.
	 * Reinitialize the cache.
     *
	 * @since 2.1
	 */
	public synchronized static void flushLocalFile() {
		entryMap = null;
	}

	/**
	 * Removes the specified key from the local file map. The file is
	 * not actually deleted until VM termination.
	 * 
	 * @param key lookup key
	 * @since 2.0
	 */
	public static synchronized void removeLocalFile(String key) {
		if (entryMap != null)
			entryMap.remove(key);
	}

	/**
	 * Copies specified input stream to the output stream. Neither stream
	 * is closed as part of this operation.
	 * 
	 * @param is input stream
	 * @param os output stream
	 * @param monitor progress monitor
	 * @exception IOException
	 * @exception InstallAbortedException
	 * @since 2.0
	 */
	public static void copy(InputStream is, OutputStream os, InstallMonitor monitor) throws IOException, InstallAbortedException {
		long offset = UpdateManagerUtils.copy(is, os, monitor, 0);
		if (offset != -1) {
			if (monitor.isCanceled()) {
				String msg = Policy.bind("Feature.InstallationCancelled"); //$NON-NLS-1$
				throw new InstallAbortedException(msg, null);
			} else {
				throw new IOException();
			}
		}
	}

	/**
	 * Creates a CoreException from some other exception.
	 * The type of the CoreException is <code>IStatus.ERROR</code>
	 * If the exception passed as a parameter is also a CoreException,
	 * the new CoreException will contain all the status of the passed
	 * CoreException.
	 * 
	 * @see IStatus#ERROR
	 * @param s exception string
	 * @param code the code reported
	 * @param e actual exception being reported
	 * @return a CoreException
	 * @since 2.0
	 */
	public static CoreException newCoreException(String s, int code, Throwable e) {
		String id = UpdateCore.getPlugin().getBundle().getSymbolicName();

		// check the case of a multistatus
		IStatus status;
		if (e instanceof FeatureDownloadException)
			return (FeatureDownloadException)e;
		else if (e instanceof CoreException) {
			if (s == null)
				s = ""; //$NON-NLS-1$
			status = new MultiStatus(id, code, s, e);
			IStatus childrenStatus = ((CoreException) e).getStatus();
			((MultiStatus) status).add(childrenStatus);
			((MultiStatus) status).addAll(childrenStatus);
		} else {
			StringBuffer completeString = new StringBuffer(""); //$NON-NLS-1$
			if (s != null)
				completeString.append(s);
			if (e != null) {
				completeString.append(" ["); //$NON-NLS-1$
				String msg = e.getLocalizedMessage();
				completeString.append(msg!=null?msg:e.toString());
				completeString.append("]"); //$NON-NLS-1$
			}
			status = new Status(IStatus.ERROR, id, code, completeString.toString(), e);
		}
		return new CoreException(status); //$NON-NLS-1$
	}

	/**
	 * Creates a CoreException from some other exception.
	 * The type of the CoreException is <code>IStatus.ERROR</code>
	 * If the exceptionpassed as a parameter is also a CoreException,
	 * the new CoreException will contain all the status of the passed
	 * CoreException.
	 * 
	 * @see IStatus#ERROR
	 * @param s exception string
	 * @param e actual exception being reported
	 * @return a CoreException
	 * @since 2.0
	 */
	public static CoreException newCoreException(String s, Throwable e) {
		return newCoreException(s, IStatus.OK, e);
	}

	/**
	 * Creates a CoreException from two other CoreException
	 * 
	 * @param s overall exception string
	 * @param s1 string for first detailed exception
	 * @param s2 string for second detailed exception
	 * @param e1 first detailed exception
	 * @param e2 second detailed exception
	 * @return a CoreException with multi-status
	 * @since 2.0
	 */
	public static CoreException newCoreException(String s, String s1, String s2, CoreException e1, CoreException e2) {
		String id = UpdateCore.getPlugin().getBundle().getSymbolicName();
		if (s == null)
			s = ""; //$NON-NLS-1$

		IStatus childStatus1 = ((CoreException) e1).getStatus();
		IStatus childStatus2 = ((CoreException) e2).getStatus();
		int code = (childStatus1.getCode() == childStatus2.getCode()) ? childStatus1.getCode() : IStatus.OK;
		MultiStatus multi = new MultiStatus(id, code, s, null);

		multi.add(childStatus1);
		multi.addAll(childStatus1);
		multi.add(childStatus2);
		multi.addAll(childStatus2);

		return new CoreException(multi); //$NON-NLS-1$
	}

	/**
	 * Formats a Date based on the default Locale 
	 * If teh Date is <code>null</code> returns an empty String
	 * 
	 * @param date the Date to format
	 * @return the formatted Date as a String
	 * @since 2.0
	 */
	public static String format(Date date) {
		if (date == null)
			return ""; //$NON-NLS-1$
		return dateFormat.format(date);
	}

	/**
	 * Perform shutdown processing for temporary file handling.
	 * This method is called when platform is shutting down.
	 * It is not intended to be called at any other time under
	 * normal circumstances. A side-effect of calling this method
	 * is that the contents of the temporary directory managed 
	 * by this class are deleted. 
	 * 
	 * @since 2.0
	 */
	public static void shutdown() {
		if (dirRoot == null)
			return;

		File temp = new File(dirRoot); // temp directory root for this run
		cleanupTemp(temp);
		temp.delete();
	}

	private static void cleanupTemp(File root) {
		File[] files = root.listFiles();
		for (int i = 0; files != null && i < files.length; i++) {
			if (files[i].isDirectory())
				cleanupTemp(files[i]);
			files[i].delete();
		}
	}

	private static void verifyPath(File path, boolean isFile) {
		// if we are expecting a file back off 1 path element
		if (isFile) {
			if (path.getAbsolutePath().endsWith(File.separator)) {
				// make sure this is a file
				path = path.getParentFile();
				isFile = false;
			}
		}

		// already exists ... just return
		if (path.exists())
			return;

		// does not exist ... ensure parent exists
		File parent = path.getParentFile();
		verifyPath(parent, false);

		// ensure directories are made. Mark files or directories for deletion
		if (!isFile)
			path.mkdir();
		path.deleteOnExit();
	}
}
