/*******************************************************************************
 *  Copyright (c) 2000, 2010 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.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

import org.eclipse.osgi.util.NLS;
import org.eclipse.update.internal.core.FatalIOException;
import org.eclipse.update.internal.core.Messages;
import org.eclipse.update.internal.core.URLEncoder;
import org.eclipse.update.internal.core.UpdateManagerUtils;
import org.eclipse.update.internal.core.connection.ConnectionFactory;
import org.eclipse.update.internal.core.connection.HttpResponse;
import org.eclipse.update.internal.core.connection.IResponse;

/**
 * Content reference implements a general access wrapper 
 * to feature and site content. The reference specifies
 * a "symbolic" path identifier for the content, and the actual
 * reference as a file, or a URL.
 * <p>
 * This class may be instantiated or 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.JarContentReference
 * @see org.eclipse.update.core.JarEntryContentReference
 * @since 2.0
 * @deprecated The org.eclipse.update component has been replaced by Equinox p2.
 * This API will be deleted in a future release. See bug 311590 for details.
 */
public class ContentReference {

	/**
	 * Unknown size indication
	 * @since 2.0
	 */
	public static final long UNKNOWN_SIZE = -1;

	/**
	 * Default executable permission when installing a content reference
	 * Will add executable bit if necessary
	 * 
	 * @since 2.0.1
	 */
	public static final int DEFAULT_EXECUTABLE_PERMISSION = -1;

	private static final String FILE_URL_PROTOCOL = "file"; //$NON-NLS-1$

	private String id;
	private URL url; // reference is either URL reference *OR*
	private File file; //    local file reference
	private IResponse response;
	private int permission; 
	private long length;
	
	// <true> if a copy of a Contentreferenec in a temp local directory
	private boolean tempLocal = false;
	
	private long lastModified;

	/**
	 * Create content reference from URL.
	 * 
	 * @param id "symbolic" path identifier
	 * @param url actual referenced URL
	 * @since 2.0
	 */
	public ContentReference(String id, URL url) {
		this.id = (id == null ? "" : id); //$NON-NLS-1$
		this.url = url; // can be null
		this.file = null;
	}

	/**
	 * Create content reference from file.
	 * 
	 * @param id "symbolic" path identifier
	 * @param file actual referenced file
	 * @since 2.0
	 */
	public ContentReference(String id, File file) {
		this.id = (id == null ? "" : id); //$NON-NLS-1$
		this.file = file; // can be null
		this.url = null;
	}

	/**
	 * A factory method to create a content reference of
	 * the same type.
	 * 
	 * @param id "symbolic" path identifier
	 * @param file actual referenced file
	 * @return content reference of the same type
	 * @since 2.0
	 */
	public ContentReference createContentReference(String id, File file) {
		return new ContentReference(id, file,true);
	}
	/**
	 * 
	 */
	private ContentReference(String id, File file, boolean b) {
		this(id,file);
		setTempLocal(b);
	}

	/**
	 * Retrieves the "symbolic" path identifier for the reference.
	 * 
	 * @return "symbolic" path identifier
	 * @since 2.0
	 */
	public String getIdentifier() {
		return id;
	}

	/**
	 * Creates an input stream for the reference.
	 * 
	 * @return input stream
	 * @exception IOException unable to create stream
	 * @since 2.0
	 */
	public InputStream getInputStream() throws IOException {
		if (file != null)
			return new FileInputStream(file);
		else if (url != null) {
			if (response == null) {
				URL resolvedURL = URLEncoder.encode(url);
				response = ConnectionFactory.get(resolvedURL);
				UpdateManagerUtils.checkConnectionResult(response,resolvedURL);
			}
			InputStream is=response.getInputStream();
			length=response.getContentLength();
			return is;
		} else
			throw new FatalIOException(NLS.bind(Messages.ContentReference_UnableToCreateInputStream, (new String[] { this.toString() })));
	}
	/**
	 * Creates an input stream for the reference.
	 * 
	 * @return input stream
	 * @exception IOException unable to create stream
	 * @since 2.0
	 */
	InputStream getPartialInputStream(long offset) throws IOException {
		if (url != null && "http".equals(url.getProtocol())) { //$NON-NLS-1$
			URL resolvedURL = URLEncoder.encode(url);
			response = ConnectionFactory.get(resolvedURL);
			if(response instanceof HttpResponse)
				((HttpResponse)response).setOffset(offset);
			UpdateManagerUtils.checkConnectionResult(response,resolvedURL);
			InputStream is = response.getInputStream();
			length=offset + response.getContentLength();
			return is;
		} else
			throw new FatalIOException(NLS.bind(Messages.ContentReference_UnableToCreateInputStream, (new String[] { this.toString() })));
	}
	
	/**
	 * Returns the size of the referenced input, if it can be determined.
	 * 
	 * @return input size, or @see #UNKNOWN_SIZE if size cannot be determined.
	 * @since 2.0
	 */
	public long getInputSize() throws IOException {
		if (length>0)
			return length;
		if (file != null)
			return file.length();
		else if (url != null) {
			if (response == null) {
				URL resolvedURL = null;
				try {
					resolvedURL = URLEncoder.encode(url);
					response = ConnectionFactory.get(resolvedURL);
				} catch (IOException e) {
					return ContentReference.UNKNOWN_SIZE;
				}
				UpdateManagerUtils.checkConnectionResult(response,resolvedURL);			
			}
			long size = response.getContentLength();
			return size == -1 ? ContentReference.UNKNOWN_SIZE : size;
		} else
			return ContentReference.UNKNOWN_SIZE;
	}

	/**
	 * Indicates whether the reference is a local file reference.
	 * 
	 * @return <code>true</code> if the reference is local, 
	 * otherwise <code>false</code>
	 * @since 2.0
	 */
	public boolean isLocalReference() {
		/*if (file != null)
			return true;
		else if (url != null)
			return FILE_URL_PROTOCOL.equals(url.getProtocol());
		else
			return false;*/
		// only temp files are considered local
		return tempLocal;
	}

	/**
	 * Returns the content reference as a file. Note, that this method
	 * <b>does not</b> cause the file to be downloaded if it
	 * is not already local.
	 * 
	 * @return reference as file
	 * @exception IOException reference cannot be returned as file
	 * @since 2.0
	 */
	public File asFile() throws IOException {
		if (file != null)
			return file;

		if (url != null && FILE_URL_PROTOCOL.equals(url.getProtocol())) {
			File result = new File(url.getFile());
			if (result.exists())
				return result;
			else 
				throw new IOException(NLS.bind(Messages.ContentReference_FileDoesNotExist, (new String[] { this.toString() }))); 			
		}

		throw new IOException(NLS.bind(Messages.ContentReference_UnableToReturnReferenceAsFile, (new String[] { this.toString() }))); 
	}

	/**
	 * Returns the content reference as a URL.
	 * 
	 * @return reference as URL
	 * @exception IOException reference cannot be returned as URL
	 * @since 2.0
	 */
	public URL asURL() throws IOException {
		if (url != null)
			return url;

		if (file != null)
			return file.toURL();

		throw new FatalIOException(NLS.bind(Messages.ContentReference_UnableToReturnReferenceAsURL, (new String[] { this.toString() })));
	}

	/**
	 * Return string representation of this reference.
	 * 
	 * @return string representation
	 * @since 2.0
	 */
	public String toString() {
		if (file != null)
			return file.getAbsolutePath();
		else
			return url.toExternalForm();
	}
	/**
	 * Returns the permission for this file.
	 * 
	 * @return the content reference permission
	 * @see #DEFAULT_EXECUTABLE_PERMISSION
	 * @since 2.0.1
	 */
	public int getPermission() {
		return permission;
	}

	/**
	 * Sets the permission of this content reference.
	 * 
	 * @param permission The permission to set
	 */
	public void setPermission(int permission) {
		this.permission = permission;
	}

	/**
	 * Sets if a content reference is considered local 
	 * 
	 * @param tempLocal <code>true</code> if the file is considered local
	 */
	protected void setTempLocal(boolean tempLocal) {
		this.tempLocal = tempLocal;
	}
	
	/**
	 * Sets the timestamp the content was last modified.
	 * @param timestamp
	 * @since 3.0
	 */
	public void setLastModified(long timestamp) {
		this.lastModified = timestamp;
	}
	
	/**
	 * Returns the timestamp when the content was last modified
	 * @return the timestamp
	 * @since 3.0
	 */
	public long getLastModified() {
		if (lastModified == 0) {
			if (file != null) 
				lastModified = file.lastModified();
			else if (url != null) {
				if (response == null) {
					try {
						URL resolvedURL = URLEncoder.encode(url);
						response = ConnectionFactory.get(resolvedURL);
					} catch (MalformedURLException e) {
						// return 0
					} catch (IOException e) {
						// return 0
					}
				}
				lastModified = response.getLastModified();
			} 
		}
		return lastModified;
	}
}
