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