/*******************************************************************************
 * Copyright (c) 2006-2009, Cloudsmith Inc.
 * The code, documentation and other materials contained herein have been
 * licensed under the Eclipse Public License - v 1.0 by the copyright holder
 * listed above, as the Initial Contributor under such license. The text of
 * such license is available at www.eclipse.org.
 ******************************************************************************/
package org.eclipse.equinox.internal.p2.repository;

import java.io.*;
import java.net.URI;
import java.util.Date;
import org.eclipse.core.runtime.*;
import org.eclipse.ecf.core.security.IConnectContext;
import org.eclipse.ecf.filetransfer.*;
import org.eclipse.ecf.filetransfer.events.*;
import org.eclipse.ecf.filetransfer.identity.*;
import org.eclipse.ecf.filetransfer.service.IRetrieveFileTransferFactory;
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
import org.eclipse.osgi.util.NLS;

/**
 * @author Thomas Hallgren
 * @author henrik.lindberg@cloudsmith.com - adaption to 1.4 and to this p2 package
 */
public class FileReader extends FileTransferJob implements IFileTransferListener {
	private boolean closeStreamWhenFinished = false;
	private Exception exception;
	private FileInfo fileInfo;
	private long lastProgressCount;
	private long lastStatsCount;
	private IProgressMonitor theMonitor;
	private OutputStream theOutputStream;
	private ProgressStatistics statistics;
	private final int connectionRetryCount;
	private final long connectionRetryDelay;
	private final IConnectContext connectContext;

	/**
	 * Create a new FileReader that will retry failed connection attempts and sleep some amount of time between each
	 * attempt.
	 */
	public FileReader(IConnectContext aConnectContext) {
		super(Messages.FileTransport_reader); // job label

		// Hide this job.
		setSystem(true);
		setUser(false);
		connectionRetryCount = RepositoryPreferences.getConnectionRetryCount();
		connectionRetryDelay = RepositoryPreferences.getConnectionMsRetryDelay();
		connectContext = aConnectContext;
	}

	public FileInfo getLastFileInfo() {
		return fileInfo;
	}

	public synchronized void handleTransferEvent(IFileTransferEvent event) {
		if (event instanceof IIncomingFileTransferReceiveStartEvent) {
			IIncomingFileTransfer source = ((IIncomingFileTransferEvent) event).getSource();
			try {
				FileInfo fi = new FileInfo();
				Date lastModified = source.getRemoteLastModified();
				if (lastModified != null)
					fi.setLastModified(lastModified.getTime());
				fi.setName(source.getRemoteFileName());
				fi.setSize(source.getFileLength());
				fileInfo = fi;

				((IIncomingFileTransferReceiveStartEvent) event).receive(theOutputStream, this);
			} catch (IOException e) {
				exception = e;
				return;
			}

			if (theMonitor != null) {
				long fileLength = source.getFileLength();
				statistics = new ProgressStatistics(source.getRemoteFileName(), fileLength);
				theMonitor.beginTask(null, 1000);
				theMonitor.subTask(statistics.report());
				lastStatsCount = 0;
				lastProgressCount = 0;
			}
		} else if (event instanceof IIncomingFileTransferReceiveDataEvent) {
			IIncomingFileTransfer source = ((IIncomingFileTransferEvent) event).getSource();
			if (theMonitor != null) {
				if (theMonitor.isCanceled()) {
					source.cancel();
					return;
				}

				long br = source.getBytesReceived();
				long count = br - lastStatsCount;
				lastStatsCount = br;
				statistics.increase(count);
				fileInfo.setAverageSpeed(statistics.getAverageSpeed());
				if (statistics.shouldReport()) {
					count = br - lastProgressCount;
					lastProgressCount = br;
					theMonitor.subTask(statistics.report());
					theMonitor.worked((int) (1000 * count / statistics.getTotal()));
				}
			}
		} else if (event instanceof IIncomingFileTransferReceiveDoneEvent) {
			if (closeStreamWhenFinished)
				hardClose(theOutputStream);

			if (exception == null)
				exception = ((IIncomingFileTransferReceiveDoneEvent) event).getException();
		}
	}

	public InputStream read(URI url) throws CoreException, FileNotFoundException, AuthenticationFailedException {
		final PipedInputStream input = new PipedInputStream();
		PipedOutputStream output;
		try {
			output = new PipedOutputStream(input);
		} catch (IOException e) {
			throw RepositoryStatusHelper.wrap(e);
		}
		RepositoryTracing.debug("Downloading {0}", url); //$NON-NLS-1$

		final IProgressMonitor cancellationMonitor = new NullProgressMonitor();
		sendRetrieveRequest(url, output, true, cancellationMonitor);

		return new InputStream() {
			public int available() throws IOException {
				checkException();
				return input.available();
			}

			public void close() throws IOException {
				cancellationMonitor.setCanceled(true);
				hardClose(input);
				checkException();
			}

			public void mark(int readlimit) {
				input.mark(readlimit);
			}

			public boolean markSupported() {
				return input.markSupported();
			}

			public int read() throws IOException {
				checkException();
				return input.read();
			}

			public int read(byte b[]) throws IOException {
				checkException();
				return input.read(b);
			}

			public int read(byte b[], int off, int len) throws IOException {
				checkException();
				return input.read(b, off, len);
			}

			public void reset() throws IOException {
				checkException();
				input.reset();
			}

			public long skip(long n) throws IOException {
				checkException();
				return input.skip(n);
			}

			private void checkException() throws IOException {
				if (getException() == null)
					return;

				IOException e;
				Throwable t = RepositoryStatusHelper.unwind(getException());
				if (t instanceof IOException)
					e = (IOException) t;
				else {
					e = new IOException(t.getMessage());
					e.initCause(t);
				}
				throw e;
			}
		};
	}

	/** Only request info
	 * @deprecated REMOVE THIS METHOD - SHOULD USE BROWSE INSTEAD TO ONLY GET HEAD - ALSO REMOVE PARAMTER ONLYHEAD
	 * @param uri
	 * @return FileInfo
	 * @throws CoreException
	 * @throws FileNotFoundException
	 * @throws AuthenticationFailedException
	 */
	public FileInfo readInfo(URI uri) throws CoreException, FileNotFoundException, AuthenticationFailedException {
		sendRetrieveRequest(uri, null, false, null);
		return getLastFileInfo();
	}

	public void readInto(URI uri, OutputStream anOutputStream, IProgressMonitor monitor) //
			throws CoreException, FileNotFoundException, AuthenticationFailedException {
		try {
			sendRetrieveRequest(uri, anOutputStream, false, monitor);
			join();
		} catch (InterruptedException e) {
			monitor.setCanceled(true);
			throw new OperationCanceledException();
		} finally {
			if (monitor != null) {
				if (statistics == null)
					//
					// Monitor was never started. See to that it's balanced
					//
					monitor.beginTask(null, 1);
				else
					statistics = null;
				monitor.done();
			}
		}
	}

	protected void sendRetrieveRequest(URI uri, OutputStream outputStream, boolean closeStreamOnFinish, //
			IProgressMonitor monitor) throws CoreException, FileNotFoundException, AuthenticationFailedException {

		IRetrieveFileTransferFactory factory = Activator.getDefault().getRetrieveFileTransferFactory();
		if (factory == null) {
			throw RepositoryStatusHelper.fromMessage(Messages.ecf_configuration_error);
		}
		IRetrieveFileTransferContainerAdapter adapter = factory.newInstance();

		adapter.setConnectContextForAuthentication(connectContext);

		this.exception = null;
		this.closeStreamWhenFinished = closeStreamOnFinish;
		this.fileInfo = null;
		this.statistics = null;
		this.lastProgressCount = 0L;
		this.lastStatsCount = 0L;
		this.theMonitor = monitor;
		this.theOutputStream = outputStream;

		for (int retryCount = 0;;) {
			if (monitor != null && monitor.isCanceled())
				throw new OperationCanceledException();

			try {
				IFileID fileID = FileIDFactory.getDefault().createFileID(adapter.getRetrieveNamespace(), uri.toString());
				adapter.sendRetrieveRequest(fileID, this, null);
			} catch (IncomingFileTransferException e) {
				exception = e;
			} catch (FileCreateException e) {
				exception = e;
			}

			// note that 'exception' could have been captured in a callback
			if (exception != null) {
				// if this is a authentication failure - it is not meaningful to continue
				RepositoryStatusHelper.checkPermissionDenied(exception);

				Throwable t = RepositoryStatusHelper.unwind(exception);
				if (t instanceof CoreException)
					throw RepositoryStatusHelper.unwindCoreException((CoreException) t);

				if (t instanceof FileNotFoundException)
					//
					// Connection succeeded but the target doesn't exist
					//
					throw (FileNotFoundException) t;

				if (t instanceof IOException && retryCount < connectionRetryCount) {
					// TODO: Retry only certain exceptions or filter out
					// some exceptions not worth retrying
					//
					++retryCount;
					exception = null;
					try {
						LogHelper.log(new Status(IStatus.WARNING, Activator.ID, NLS.bind(Messages.connection_to_0_failed_on_1_retry_attempt_2, new String[] {uri.toString(), t.getMessage(), String.valueOf(retryCount)}), t));

						Thread.sleep(connectionRetryDelay);
						continue;
					} catch (InterruptedException e) {
						/* ignore */
					}
				}
				throw RepositoryStatusHelper.wrap(exception);
			}
			break;
		}
	}

	protected Exception getException() {
		return exception;
	}

	/**
	 * Closes input and output streams
	 * @param aStream
	 */
	public static void hardClose(Object aStream) {
		if (aStream != null) {
			try {
				if (aStream instanceof OutputStream)
					((OutputStream) aStream).close();
				else if (aStream instanceof InputStream)
					((InputStream) aStream).close();
			} catch (IOException e) { /* ignore */
			}
		}
	}

}
