/*******************************************************************************
 *  Copyright (c) 2000, 2009 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.update.core;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.osgi.util.NLS;
import org.eclipse.update.core.model.ContentEntryModel;
import org.eclipse.update.core.model.InstallAbortedException;
import org.eclipse.update.core.model.NonPluginEntryModel;
import org.eclipse.update.core.model.PluginEntryModel;
import org.eclipse.update.internal.core.FatalIOException;
import org.eclipse.update.internal.core.FeatureDownloadException;
import org.eclipse.update.internal.core.FileFragment;
import org.eclipse.update.internal.core.InternalSiteManager;
import org.eclipse.update.internal.core.LockManager;
import org.eclipse.update.internal.core.Messages;
import org.eclipse.update.internal.core.UpdateCore;
import org.eclipse.update.internal.core.UpdateManagerUtils;

/**
 * Base implementation of a feature content provider. This class provides a set
 * of helper methods useful for implementing feature content providers. In
 * particular, methods dealing with downloading and caching of feature files.
 * <p>
 * This class must be subclassed by clients.
 * </p>
 * <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>
 * @see org.eclipse.update.core.IFeatureContentProvider
 * @since 2.0
 * @deprecated The org.eclipse.update component has been replaced by Equinox p2. This
 * provisional API was never promoted to stable API, and may be removed from a future release of the platform.
 */
public abstract class FeatureContentProvider implements IFeatureContentProvider {

	/**
	 *  
	 */
	public class FileFilter {

		private IPath filterPath = null;

		/**
		 * Constructor for FileFilter.
		 */
		public FileFilter(String filter) {
			super();
			this.filterPath = new Path(filter);
		}

		/**
		 * returns true if the name matches the rule
		 */
		public boolean accept(String name) {

			if (name == null)
				return false;

			// no '*' pattern matching
			// must be equals
			IPath namePath = new Path(name);
			if (filterPath.lastSegment().indexOf('*') == -1) {
				return filterPath.equals(namePath);
			}

			// check same file extension if extension exists (a.txt/*.txt)
			// or same file name (a.txt,a.*)
			String extension = filterPath.getFileExtension();
			if (extension != null && !extension.equals("*")) { //$NON-NLS-1$
				if (!extension.equalsIgnoreCase(namePath.getFileExtension()))
					return false;
			} else {
				IPath noExtension = filterPath.removeFileExtension();
				String fileName = noExtension.lastSegment();
				if (!fileName.equals("*")) { //$NON-NLS-1$
					if (!namePath.lastSegment().startsWith(fileName))
						return false;
				}
			}

			// check same path
			IPath p1 = namePath.removeLastSegments(1);
			IPath p2 = filterPath.removeLastSegments(1);
			return p1.equals(p2);
		}

	}

	private URL base;
	private IFeature feature;
	private File tmpDir; // local work area for each provider
	public static final String JAR_EXTENSION = ".jar"; //$NON-NLS-1$	

	private static final String DOT_PERMISSIONS = "permissions.properties"; //$NON-NLS-1$
	private static final String EXECUTABLES = "permissions.executable"; //$NON-NLS-1$

	/**
	 * Feature content provider constructor
	 * 
	 * @param base
	 *            feature URL. The interpretation of this URL is specific to
	 *            each content provider.
	 * @since 2.0
	 */
	public FeatureContentProvider(URL base) {
		this.base = base;
		this.feature = null;
	}

	/**
	 * Returns the feature url.
	 * 
	 * @see IFeatureContentProvider#getURL()
	 */
	public URL getURL() {
		return base;
	}

	/**
	 * Returns the feature associated with this content provider.
	 * 
	 * @see IFeatureContentProvider#getFeature()
	 */
	public IFeature getFeature() {
		return feature;
	}

	/**
	 * Sets the feature associated with this content provider.
	 * 
	 * @see IFeatureContentProvider#setFeature(IFeature)
	 */
	public void setFeature(IFeature feature) {
		this.feature = feature;
	}

	/**
	 * Returns the specified reference as a local file system reference. If
	 * required, the file represented by the specified content reference is
	 * first downloaded to the local system
	 * 
	 * @param ref
	 *            content reference
	 * @param monitor
	 *            progress monitor, can be <code>null</code>
	 * @exception IOException
	 * @exception CoreException
	 * @since 2.0
	 */
	public ContentReference asLocalReference(ContentReference ref, InstallMonitor monitor) throws IOException, CoreException {

		// check to see if this is already a local reference
		if (ref.isLocalReference())
			return ref;

		// check to see if we already have a local file for this reference
		String key = ref.toString();

		// need to synch as another thread my have created the file but
		// is still copying into it
		File localFile = null;
		FileFragment localFileFragment = null;
		Object keyLock = LockManager.getLock(key);
		synchronized (keyLock) {
			localFile = Utilities.lookupLocalFile(key);
			if (localFile != null) {
				// check if the cached file is still valid (no newer version on
				// server)
				try {
				if (UpdateManagerUtils.isSameTimestamp(ref.asURL(), localFile.lastModified()))
					return ref.createContentReference(ref.getIdentifier(), localFile);
				} catch(FatalIOException e) {
					throw e;
				} catch(IOException e) {
					throw new FeatureDownloadException(NLS.bind(Messages.FeatureContentProvider_ExceptionDownloading, (new Object[] {getURL().toExternalForm()})), e);
				}
			}

			if (localFile == null) {
				localFileFragment = UpdateManagerUtils.lookupLocalFileFragment(key);
			}
			// 
			// download the referenced file into local temporary area
			InputStream is = null;
			OutputStream os = null;
			long bytesCopied = 0;
			long inputLength = 0;
			boolean success = false;
			if (monitor != null) {
				monitor.saveState();
				monitor.setTaskName(Messages.FeatureContentProvider_Downloading);
				monitor.subTask(ref.getIdentifier() + " "); //$NON-NLS-1$
				try {
					monitor.setTotalCount(ref.getInputSize());
				} catch (FatalIOException e) {
					throw e;
				} catch (IOException e) {
					throw new FeatureDownloadException(NLS.bind(Messages.FeatureContentProvider_ExceptionDownloading, (new Object[] {getURL().toExternalForm()})), e);
				}
				monitor.showCopyDetails(true);
			}

			try {
				//long startTime = System.nanoTime();
				if (localFileFragment != null && "http".equals(ref.asURL().getProtocol())) { //$NON-NLS-1$
					localFile = localFileFragment.getFile();
					try {
						// get partial input stream
						is = ref.getPartialInputStream(localFileFragment.getSize());
						inputLength = ref.getInputSize() - localFileFragment.getSize();
						// get output stream to append to file fragment
						os = new BufferedOutputStream(
						// PAL foundation
								//new FileOutputStream(localFile, true));
								new FileOutputStream(localFile.getPath(), true));
					} catch (FatalIOException e) {
						throw e;
					} catch (IOException e) {
						try {
							if (is != null)
								is.close();
						} catch (IOException ioe) {
						}
						is = null;
						os = null;
						localFileFragment = null;
						throw new FeatureDownloadException(NLS.bind(Messages.FeatureContentProvider_ExceptionDownloading, (new Object[] {getURL().toExternalForm()})), e);
					}
				}
				if (is == null) {
					// must download from scratch
					localFile = Utilities.createLocalFile(getWorkingDirectory(), null);
					try {
						is = ref.getInputStream();
						inputLength = ref.getInputSize();
					} catch (FatalIOException e) {
						throw Utilities.newCoreException(NLS.bind(Messages.FeatureContentProvider_UnableToRetrieve, (new Object[] {ref})), e);
					} catch (IOException e) {
						throw new FeatureDownloadException(NLS.bind(Messages.FeatureContentProvider_ExceptionDownloading, (new Object[] {getURL().toExternalForm()})), e);
					}

					try {
						os = new BufferedOutputStream(new FileOutputStream(localFile));
					} catch (FileNotFoundException e) {
						throw Utilities.newCoreException(NLS.bind(Messages.FeatureContentProvider_UnableToCreate, (new Object[] {localFile})), e);
					}
				}

				Date start = new Date();
				if (localFileFragment != null) {
					bytesCopied = localFileFragment.getSize();
					if (monitor != null) {
						monitor.setCopyCount(bytesCopied);
					}
				}

				// Transfer as many bytes as possible from input to output stream
				long offset = UpdateManagerUtils.copy(is, os, monitor, inputLength);
				if (offset != -1) {
					bytesCopied += offset;
					if (bytesCopied > 0) {
						// preserve partially downloaded file
						UpdateManagerUtils.mapLocalFileFragment(key, new FileFragment(localFile, bytesCopied));
					}
					if (monitor != null && monitor.isCanceled()) {
						String msg = Messages.Feature_InstallationCancelled;
						throw new InstallAbortedException(msg, null);
					} else {
						throw new FeatureDownloadException(NLS.bind(Messages.FeatureContentProvider_ExceptionDownloading, (new Object[] {getURL().toExternalForm()})), new IOException());
					}
				} else {
					UpdateManagerUtils.unMapLocalFileFragment(key);
				}

				Date stop = new Date();
				long timeInseconds = (stop.getTime() - start.getTime()) / 1000;
				// time in milliseconds /1000 = time in seconds
				InternalSiteManager.downloaded(
					ref.getInputSize(),
					(timeInseconds),
					ref.asURL());

				success = true;
				//long endTime = System.nanoTime();
				// file is downloaded succesfully, map it
				Utilities.mapLocalFile(key, localFile);
				
				/*if (ref.asURL().toExternalForm().endsWith("jar")) {
					synchronized(this.getClass()) {
						timer += (endTime - startTime);
						if (first == 0) {
							first = endTime - startTime;
						}
					}
				}*/
			} catch (ClassCastException e) {
				throw Utilities.newCoreException(
					NLS.bind(Messages.FeatureContentProvider_UnableToCreate, (new Object[] { localFile })),
					e);
			} finally {
				//Do not close IS if user cancel,
				//closing IS will read the entire Stream until the end
				if (success && is != null)
					try {
						is.close();
					} catch (IOException e) {
					}
				if (os != null)
					try {
						os.close(); // should flush buffer stream
					} catch (IOException e) {
					}

				if (success || bytesCopied > 0) {
					// set the timestamp on the temp file to match the remote
					// timestamp
					localFile.setLastModified(ref.getLastModified());
				}
				if (monitor != null)
					monitor.restoreState();
			}
			LockManager.returnLock(key);
		} // end lock
		ContentReference reference =
			ref.createContentReference(ref.getIdentifier(), localFile);
		
		UpdateCore.getPlugin().getUpdateSession().markVisited(ref.asURL());
		
		return reference;
	}

	/**
	 * Returns the specified reference as a local file. If required, the file
	 * represented by the specified content reference is first downloaded to
	 * the local system
	 * 
	 * @param ref
	 *            content reference
	 * @param monitor
	 *            progress monitor, can be <code>null</code>
	 * @exception IOException
	 * @exception CoreException
	 * @since 2.0
	 */
	public File asLocalFile(ContentReference ref, InstallMonitor monitor) throws IOException, CoreException {
		File file = ref.asFile();
		ContentReference localRef = asLocalReference(ref, monitor);
		file = localRef.asFile();
		return file;
	}

	/**
	 * Returns working directory for this content provider
	 * 
	 * @return working directory
	 * @exception IOException
	 * @since 2.0
	 */
	protected File getWorkingDirectory() throws IOException {
		if (tmpDir == null)
			tmpDir = Utilities.createWorkingDirectory();
		return tmpDir;
	}

	/**
	 * Returns the total size of all archives required for the specified
	 * plug-in and non-plug-in entries (the "packaging" view).
	 * 
	 * @see IFeatureContentProvider#getDownloadSizeFor(IPluginEntry[],
	 *      INonPluginEntry[])
	 */
	public long getDownloadSizeFor(IPluginEntry[] pluginEntries, INonPluginEntry[] nonPluginEntries) {
		long result = 0;

		// if both are null or empty, return UNKNOWN size
		if ((pluginEntries == null || pluginEntries.length == 0) && (nonPluginEntries == null || nonPluginEntries.length == 0)) {
			return ContentEntryModel.UNKNOWN_SIZE;
		}

		// loop on plugin entries
		long size = 0;
		if (pluginEntries != null)
			for (int i = 0; i < pluginEntries.length; i++) {
				size = ((PluginEntryModel) pluginEntries[i]).getDownloadSize();
				if (size == ContentEntryModel.UNKNOWN_SIZE) {
					return ContentEntryModel.UNKNOWN_SIZE;
				}
				result += size;
			}

		// loop on non plugin entries
		if (nonPluginEntries != null)
			for (int i = 0; i < nonPluginEntries.length; i++) {
				size = ((NonPluginEntryModel) nonPluginEntries[i]).getDownloadSize();
				if (size == ContentEntryModel.UNKNOWN_SIZE) {
					return ContentEntryModel.UNKNOWN_SIZE;
				}
				result += size;
			}

		return result;
	}

	/**
	 * Returns the total size of all files required for the specified plug-in
	 * and non-plug-in entries (the "logical" view).
	 * 
	 * @see IFeatureContentProvider#getInstallSizeFor(IPluginEntry[],
	 *      INonPluginEntry[])
	 */
	public long getInstallSizeFor(IPluginEntry[] pluginEntries, INonPluginEntry[] nonPluginEntries) {
		long result = 0;

		// if both are null or empty, return UNKNOWN size
		if ((pluginEntries == null || pluginEntries.length == 0) && (nonPluginEntries == null || nonPluginEntries.length == 0)) {
			return ContentEntryModel.UNKNOWN_SIZE;
		}

		// loop on plugin entries
		long size = 0;
		if (pluginEntries != null)
			for (int i = 0; i < pluginEntries.length; i++) {
				size = ((PluginEntryModel) pluginEntries[i]).getInstallSize();
				if (size == ContentEntryModel.UNKNOWN_SIZE) {
					return ContentEntryModel.UNKNOWN_SIZE;
				}
				result += size;
			}

		// loop on non plugin entries
		if (nonPluginEntries != null)
			for (int i = 0; i < nonPluginEntries.length; i++) {
				size = ((NonPluginEntryModel) nonPluginEntries[i]).getInstallSize();
				if (size == ContentEntryModel.UNKNOWN_SIZE) {
					return ContentEntryModel.UNKNOWN_SIZE;
				}
				result += size;
			}

		return result;
	}

	/**
	 * Returns the path identifier for a plugin entry. <code>plugins/&lt;pluginId>_&lt;pluginVersion>.jar</code>
	 * 
	 * @return the path identifier
	 */
	protected String getPathID(IPluginEntry entry) {
		return Site.DEFAULT_PLUGIN_PATH + entry.getVersionedIdentifier().toString() + JAR_EXTENSION;
	}

	/**
	 * Returns the path identifer for a non plugin entry. <code>features/&lt;featureId>_&lt;featureVersion>/&lt;dataId></code>
	 * 
	 * @return the path identifier
	 */
	protected String getPathID(INonPluginEntry entry) {
		String nonPluginBaseID = Site.DEFAULT_FEATURE_PATH + feature.getVersionedIdentifier().toString() + "/"; //$NON-NLS-1$
		return nonPluginBaseID + entry.getIdentifier();
	}

	/**
	 * Sets the permission of all the ContentReferences Check for the
	 * .permissions contentReference and use it to set the permissions of other
	 * ContentReference
	 */
	protected void validatePermissions(ContentReference[] references) {

		if (references == null || references.length == 0)
			return;

		Map permissions = getPermissions(references);
		if (permissions.isEmpty())
			return;

		for (int i = 0; i < references.length; i++) {
			ContentReference contentReference = references[i];
			String id = contentReference.getIdentifier();
			Object value = null;
			if ((value = matchesOneRule(id, permissions)) != null) {
				Integer permission = (Integer) value;
				contentReference.setPermission(permission.intValue());
			}
		}
	}

	/**
	 * Returns the value of the matching rule or <code>null</code> if none
	 * found. A rule is matched if the id is equals to a key, or if the id is
	 * resolved by a key. if the id is <code>/path/file.txt</code> it is
	 * resolved by <code>/path/*</code> or <code>/path/*.txt</code>
	 * 
	 * @param id
	 *            the identifier
	 * @param permissions
	 *            list of rules
	 * @return Object the value of the matching rule or <code>null</code>
	 */
	private Object matchesOneRule(String id, Map permissions) {

		Set keySet = permissions.keySet();
		Iterator iter = keySet.iterator();
		while (iter.hasNext()) {
			FileFilter rule = (FileFilter) iter.next();
			if (rule.accept(id)) {
				return permissions.get(rule);
			}
		}

		return null;
	}

	/*
	 * returns the permission MAP
	 */
	private Map getPermissions(ContentReference[] references) {

		Map result = new HashMap();
		// search for .permissions
		boolean notfound = true;
		ContentReference permissionReference = null;
		for (int i = 0; i < references.length && notfound; i++) {
			ContentReference contentReference = references[i];
			if (DOT_PERMISSIONS.equals(contentReference.getIdentifier())) {
				notfound = false;
				permissionReference = contentReference;
			}
		}
		if (notfound)
			return result;

		Properties prop = new Properties();
		InputStream propertyStream = null;
		try {
			try {
				propertyStream = permissionReference.getInputStream();
				prop.load(propertyStream);
			} finally {
				if (propertyStream != null)
					propertyStream.close();
			}
		} catch (IOException e) {
			UpdateCore.warn("", e); //$NON-NLS-1$
		}

		String executables = prop.getProperty(EXECUTABLES);
		if (executables == null)
			return result;

		StringTokenizer tokenizer = new StringTokenizer(executables, ","); //$NON-NLS-1$
		Integer defaultExecutablePermission = new Integer(ContentReference.DEFAULT_EXECUTABLE_PERMISSION);
		while (tokenizer.hasMoreTokens()) {
			FileFilter filter = new FileFilter(tokenizer.nextToken());
			result.put(filter, defaultExecutablePermission);
		}

		return result;
	}
}
