/******************************************************************************
 * Copyright (c) 2006, 2010 VMware Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Apache License v2.0 which accompanies this distribution. 
 * The Eclipse Public License is available at 
 * http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0
 * is available at http://www.opensource.org/licenses/apache2.0.php.
 * You may elect to redistribute this code under either of these licenses. 
 * 
 * Contributors:
 *   VMware Inc.
 *****************************************************************************/

package org.eclipse.gemini.blueprint.io;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Set;

import org.eclipse.gemini.blueprint.io.internal.OsgiResourceUtils;
import org.osgi.framework.Bundle;
import org.springframework.core.io.AbstractResource;
import org.springframework.core.io.ContextResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;

/**
 * Resource implementation for OSGi environments.
 * 
 * <p/>
 * Lazy evaluation of the resource will be used.
 * 
 * This implementation allows resource location inside:
 * 
 * <ul>
 * <li><em>bundle space</em> - if <code>osgibundle:</code>/
 * {@link #BUNDLE_URL_PREFIX} prefix is being used or none is specified. This
 * space cotnains the bundle jar and its attached fragments.</li>
 * <li><em>bundle jar</em> - if <code>osgibundlejar:</code>/
 * {@link #BUNDLE_JAR_URL_PREFIX} is specified. This space contains just the
 * bundle jar.</li>
 * <li><em>class space</em> - if
 * {@link org.springframework.util.ResourceUtils#CLASSPATH_URL_PREFIX} is
 * encountered. This space contains the bundle classpath, namely the bundle jar,
 * its attached fragments and imported packages.</li>
 * </ul>
 * 
 * For more explanations on resource locations in OSGi, please see the
 * <em>Access to Resources</em> chapter from the OSGi spec.
 * 
 * <p/>
 * OSGi framework specific prefixes (such as <code>bundleentry:</code> and
 * <code>bundleresource:</code>under Equinox, <code>bundle:</code> under
 * Knopflefish and Felix, etc..) are supported. Resources outside the OSGi space
 * (<code>file:</code>, <code>http:</code>, etc..) are supported as well as the
 * path is being resolved to an <code>URL</code>.
 * 
 * <p/>
 * If no prefix is specified, the <em>bundle space</em> will be used for
 * locating a resource.
 * 
 * <p/>
 * <strong>Note:</strong> When the <em>bundle space</em> (bundle jar and its
 * attached fragments) is being searched, multiple URLs can be found but this
 * implementation will return only the first one. Consider using
 * {@link OsgiBundleResourcePatternResolver} to retrieve all entries.
 * 
 * @author Costin Leau
 * @author Adrian Colyer
 */
public class OsgiBundleResource extends AbstractResource implements ContextResource {

	/**
	 * Prefix for searching inside the owning bundle space. This translates to
	 * searching the bundle and its attached fragments. If no prefix is
	 * specified, this one will be used.
	 */
	public static final String BUNDLE_URL_PREFIX = "osgibundle:";

	/**
	 * Prefix for searching only the bundle raw jar. Will ignore attached
	 * fragments. Not used at the moment.
	 */
	public static final String BUNDLE_JAR_URL_PREFIX = "osgibundlejar:";

	private static final char PREFIX_SEPARATOR = ':';

	private static final String ABSOLUTE_PATH_PREFIX = "/";

	private final Bundle bundle;

	private final String path;

	// used to avoid removing the prefix every time the URL is required
	private final String pathWithoutPrefix;

	// Bundle resource possible searches
	private int searchType = OsgiResourceUtils.PREFIX_TYPE_NOT_SPECIFIED;


	/**
	 * 
	 * Constructs a new <code>OsgiBundleResource</code> instance.
	 * 
	 * @param bundle OSGi bundle used by this resource
	 * @param path resource path inside the bundle.
	 */
	public OsgiBundleResource(Bundle bundle, String path) {
		Assert.notNull(bundle, "Bundle must not be null");
		this.bundle = bundle;

		// check path
		Assert.notNull(path, "Path must not be null");

		this.path = StringUtils.cleanPath(path);

		this.searchType = OsgiResourceUtils.getSearchType(this.path);

		switch (this.searchType) {
			case OsgiResourceUtils.PREFIX_TYPE_NOT_SPECIFIED:
				pathWithoutPrefix = path;
				break;
			case OsgiResourceUtils.PREFIX_TYPE_BUNDLE_SPACE:
				pathWithoutPrefix = path.substring(BUNDLE_URL_PREFIX.length());
				break;
			case OsgiResourceUtils.PREFIX_TYPE_BUNDLE_JAR:
				pathWithoutPrefix = path.substring(BUNDLE_JAR_URL_PREFIX.length());
				break;
			case OsgiResourceUtils.PREFIX_TYPE_CLASS_SPACE:
				pathWithoutPrefix = path.substring(ResourceLoader.CLASSPATH_URL_PREFIX.length());
				break;
			// prefix unknown so the path will be resolved outside the context
			default:
				pathWithoutPrefix = null;
		}
	}

	/**
	 * Returns the path for this resource.
	 * 
	 * @return this resource path
	 */
	final String getPath() {
		return path;
	}

	/**
	 * Returns the bundle for this resource.
	 * 
	 * @return the resource bundle
	 */
	final Bundle getBundle() {
		return bundle;
	}

	/**
	 * Returns an <code>InputStream</code> to this resource. This implementation
	 * opens an <code>InputStream<code> for the given <code>URL</code>. It sets
	 * the <em>UseCaches</em> flag to <code>false</code>, mainly to avoid jar
	 * file locking on Windows.
	 * 
	 * @return input stream to the underlying resource
	 * @throws IOException if the stream could not be opened
	 * @see java.net.URL#openConnection()
	 * @see java.net.URLConnection#setUseCaches(boolean)
	 * @see java.net.URLConnection#getInputStream()
	 * 
	 */
	public InputStream getInputStream() throws IOException {
		URLConnection con = getURL().openConnection();
		con.setUseCaches(false);
		return con.getInputStream();
	}

	/**
	 * Locates the resource in the underlying bundle based on the prefix, if it
	 * exists. Note that the location happens per call since due to the dynamic
	 * nature of OSGi, the classpath of the bundle (among others) can change
	 * during a bundle lifecycle (depending on its imports).
	 * 
	 * @return URL to this resource
	 * @throws IOException if the resource cannot be resolved as URL, i.e. if
	 *         the resource is not available as descriptor
	 * 
	 * @see org.osgi.framework.Bundle#getEntry(String)
	 * @see org.osgi.framework.Bundle#getResource(String)
	 */
	public URL getURL() throws IOException {
		ContextResource res = null;
		URL url = null;

		switch (searchType) {
			// same as bundle space but with a different string
			case OsgiResourceUtils.PREFIX_TYPE_NOT_SPECIFIED:
				res = getResourceFromBundleSpace(pathWithoutPrefix);
				break;
			case OsgiResourceUtils.PREFIX_TYPE_BUNDLE_SPACE:
				res = getResourceFromBundleSpace(pathWithoutPrefix);
				break;
			case OsgiResourceUtils.PREFIX_TYPE_BUNDLE_JAR:
				url = getResourceFromBundleJar(pathWithoutPrefix);
				break;
			case OsgiResourceUtils.PREFIX_TYPE_CLASS_SPACE:
				url = getResourceFromBundleClasspath(pathWithoutPrefix);
				break;
			// fallback
			default:
				// just try to convert it to an URL
				url = new URL(path);
				break;
		}

		if (res != null) {
			url = res.getURL();
		}

		if (url == null) {
			throw new FileNotFoundException(getDescription() + " cannot be resolved to URL because it does not exist");
		}

		return url;
	}

	/**
	 * Resolves a resource from *the bundle space* only. Only the bundle and its
	 * attached fragments are searched for the given resource. Note that this
	 * method returns only the first URL found, discarding the rest. To retrieve
	 * the entire set, consider using {@link OsgiBundleResourcePatternResolver}.
	 * 
	 * @param bundlePath the path to resolve
	 * @return a URL to the returned resource or null if none is found
	 * @throws IOException
	 * 
	 * @see {@link org.osgi.framework.Bundle#findEntries(String, String, boolean)}
	 */
	ContextResource getResourceFromBundleSpace(String bundlePath) throws IOException {
		ContextResource[] res = getAllUrlsFromBundleSpace(bundlePath);
		return (ObjectUtils.isEmpty(res) ? null : res[0]);
	}

	/**
	 * Resolves a resource from the *bundle jar* only. Only the bundle jar is
	 * searched (its attached fragments are ignored).
	 * 
	 * @param bundlePath the path to resolve
	 * @return URL to the specified path or null if none is found
	 * @throws IOException
	 * 
	 * @see {@link Bundle#getEntry(String)}
	 */
	URL getResourceFromBundleJar(String bundlePath) throws IOException {
		return bundle.getEntry(bundlePath);
	}

	/**
	 * Resolves a resource from the bundle's classpath. This will find resources
	 * in this bundle and also in imported packages from other bundles.
	 * 
	 * @param bundlePath
	 * @return a URL to the returned resource or null if none is found
	 * 
	 * @see org.osgi.framework.Bundle#getResource(String)
	 */
	URL getResourceFromBundleClasspath(String bundlePath) {
		return bundle.getResource(bundlePath);
	}

	/**
	 * Determine if the given path is relative or absolute.
	 * 
	 * @param locationPath
	 * @return
	 */
	boolean isRelativePath(String locationPath) {
		return ((locationPath.indexOf(PREFIX_SEPARATOR) == -1) && !locationPath.startsWith(ABSOLUTE_PATH_PREFIX));
	}

	/**
	 * Returns a resource relative to this resource. This implementation creates
	 * an <code>OsgiBundleResource</code>, applying the given path relative to
	 * the path of the underlying resource of this descriptor.
	 * 
	 * @param relativePath the relative path (relative to this resource)
	 * @return the resource handle for the relative resource
	 * @throws IOException if the relative resource cannot be determined
	 * @see org.springframework.util.StringUtils#applyRelativePath(String,
	 *      String)
	 */
	public Resource createRelative(String relativePath) {
		String pathToUse = StringUtils.applyRelativePath(this.path, relativePath);
		return new OsgiBundleResource(this.bundle, pathToUse);
	}

	/**
	 * Returns the filename of this resources. This implementation returns the
	 * name of the file that this bundle path resource refers to.
	 * 
	 * @return resource filename
	 * @see org.springframework.util.StringUtils#getFilename(String)
	 */
	public String getFilename() {
		return StringUtils.getFilename(this.path);
	}

	/**
	 * Returns a <code>File</code> handle for this resource. This method does a
	 * best-effort attempt to locate the bundle resource on the file system. It
	 * is strongly recommended to use {@link #getInputStream()} method instead
	 * which works no matter if the bundles are saved (in exploded form or not)
	 * on the file system.
	 * 
	 * @return File handle to this resource
	 * @throws IOException if the resource cannot be resolved as absolute file
	 *         path, i.e. if the resource is not available in a file system
	 */
	public File getFile() throws IOException {
		// locate the file inside the bundle only known prefixes
		if (searchType != OsgiResourceUtils.PREFIX_TYPE_UNKNOWN) {
			String bundleLocation = bundle.getLocation();
			int prefixIndex = bundleLocation.indexOf(ResourceUtils.FILE_URL_PREFIX);
			if (prefixIndex > -1) {
				bundleLocation = bundleLocation.substring(prefixIndex + ResourceUtils.FILE_URL_PREFIX.length());
			}
			File file = new File(bundleLocation, path);
			if (file.exists()) {
				return file;
			}
			// fall back to the URL discovery (just in case)
		}

		try {
			return ResourceUtils.getFile(getURI(), getDescription());
		}
		catch (IOException ioe) {
			throw (IOException) new FileNotFoundException(getDescription()
					+ " cannot be resolved to absolute file path").initCause(ioe);
		}
	}

	/**
	 * <p/>
	 * This implementation returns a description that includes the bundle
	 * location.
	 */
	public String getDescription() {
		StringBuilder buf = new StringBuilder();
		buf.append("OSGi resource[");
		buf.append(this.path);
		buf.append("|bnd.id=");
		buf.append(bundle.getBundleId());
		buf.append("|bnd.sym=");
		buf.append(bundle.getSymbolicName());
		buf.append("]");

		return buf.toString();
	}

	/**
	 * <p/>
	 * This implementation compares the underlying bundle and path locations.
	 */
	public boolean equals(Object obj) {
		if (obj == this) {
			return true;
		}
		if (obj instanceof OsgiBundleResource) {
			OsgiBundleResource otherRes = (OsgiBundleResource) obj;
			return (this.path.equals(otherRes.path) && ObjectUtils.nullSafeEquals(this.bundle, otherRes.bundle));
		}
		return false;
	}

	/**
	 * <p/>
	 * This implementation returns the hash code of the underlying class path
	 * location.
	 */
	public int hashCode() {
		return this.path.hashCode();
	}

	public long lastModified() throws IOException {
		URLConnection con = getURL().openConnection();
		con.setUseCaches(false);
		long time = con.getLastModified();
		// the implementation doesn't return the proper time stamp
		if (time == 0) {
			if (OsgiResourceUtils.PREFIX_TYPE_BUNDLE_JAR == searchType)
				return bundle.getLastModified();
		}
		// there is nothing else we can do
		return time;
	}

	/**
	 * @return Returns the searchType.
	 */
	int getSearchType() {
		return searchType;
	}

	/**
	 * Used internally to get all the URLs matching a certain location. The
	 * method is required to extract the folder from the given location as well
	 * the file.
	 * 
	 * @param location location to look for
	 * @return an array of URLs
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	ContextResource[] getAllUrlsFromBundleSpace(String location) throws IOException {
		if (bundle == null)
			throw new IllegalArgumentException(
				"cannot locate items in bundle-space w/o a bundle; specify one when creating this resolver");

		Assert.notNull(location);
		Set<UrlContextResource> resources = new LinkedHashSet<UrlContextResource>(5);

		location = StringUtils.cleanPath(location);
		location = OsgiResourceUtils.stripPrefix(location);

		if (!StringUtils.hasText(location))
			location = OsgiResourceUtils.FOLDER_DELIMITER;

		// the root folder is requested (special case)
		if (OsgiResourceUtils.FOLDER_DELIMITER.equals(location)) {
			// there is no way to determine the URL to the root directly
			// through findEntries so we'll have to use another way

			// getEntry can't be used since it doesn't consider fragments
			// so we have to rely on findEntries 

			// we could ask for a known entry (such as META-INF)
			// but not all jars have a dedicated entry for it
			// so we'll just ask for whatever is present in the root
			Enumeration<URL> candidates = bundle.findEntries("/", null, false);

			// since there can be multiple root paths (when fragments are present)
			// iterate on all candidates
			while (candidates != null && candidates.hasMoreElements()) {

				URL url = candidates.nextElement();

				// determined the root path
				// we'll have to parse the string since some implementations
				// do not normalize the resulting URL resulting in mismatches
				String rootPath = OsgiResourceUtils.findUpperFolder(url.toExternalForm());
				resources.add(new UrlContextResource(rootPath));
			}
		}
		else {
			// remove leading and trailing / if any
			if (location.startsWith(OsgiResourceUtils.FOLDER_DELIMITER))
				location = location.substring(1);

			if (location.endsWith(OsgiResourceUtils.FOLDER_DELIMITER))
				location = location.substring(0, location.length() - 1);

			// do we have at least on folder or is this just a file
			boolean hasFolder = (location.indexOf(OsgiResourceUtils.FOLDER_DELIMITER) != -1);

			String path = (hasFolder ? location : OsgiResourceUtils.FOLDER_DELIMITER);
			String file = (hasFolder ? null : location);

			// find the file and path
			int separatorIndex = location.lastIndexOf(OsgiResourceUtils.FOLDER_DELIMITER);

			if (separatorIndex > -1 && separatorIndex + 1 < location.length()) {
				// update the path
				path = location.substring(0, separatorIndex);

				// determine file (if there is any)
				if (separatorIndex + 1 < location.length())
					file = location.substring(separatorIndex + 1);
			}

			Enumeration<URL> candidates = bundle.findEntries(path, file, false);
			// add the leading / to be consistent
			String contextPath = OsgiResourceUtils.FOLDER_DELIMITER + location;

			while (candidates != null && candidates.hasMoreElements()) {
				resources.add(new UrlContextResource(candidates.nextElement(), contextPath));
			}
		}

		return (ContextResource[]) resources.toArray(new ContextResource[resources.size()]);
	}

	// TODO: can this return null or throw an exception
	public String getPathWithinContext() {
		return pathWithoutPrefix;
	}

	/**
	 * Return whether this resource actually exists in physical form.
	 * <p>
	 * This method performs a definitive existence check, whereas the existence
	 * of a <code>Resource</code> handle only guarantees a valid descriptor
	 * handle.
	 * 
	 * <p/>
	 * The existence check is done by opening an InputStream to the underlying
	 * resource (overriding the default implementation which checks first for
	 * the presence of a File).
	 */
	public boolean exists() {
		try {
			InputStream is = getInputStream();
			is.close();
			return true;
		}
		catch (Throwable isEx) {
			return false;
		}
	}
}