/*******************************************************************************
 * Copyright (c) 2008-2011 Chair for Applied Software Engineering,
 * Technische Universitaet Muenchen.
 * 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:
 * Jan Finis - initial API and implementaiton
 ******************************************************************************/
package org.eclipse.emf.emfstore.internal.client.model.filetransfer;

import java.io.File;
import java.text.MessageFormat;
import java.util.Observable;
import java.util.Observer;

import org.eclipse.emf.emfstore.internal.client.model.ProjectSpace;
import org.eclipse.emf.emfstore.internal.common.model.util.ModelUtil;
import org.eclipse.emf.emfstore.internal.server.exceptions.FileNotOnServerException;
import org.eclipse.emf.emfstore.internal.server.exceptions.FileTransferException;
import org.eclipse.emf.emfstore.internal.server.model.FileIdentifier;

/**
 * An object of this class is returned from any workspace method that starts a
 * file transfer. It provides information about this file transfer and allows to
 * add Progressmonitors and Observers
 *
 * @author jfinis
 */
public final class FileDownloadStatus {

	/* PRIVATE MEMBERS */
	private final ProjectSpace transferringProjectSpace;
	private final Observable finishedObservable = new Obs();
	private final Observable failedObservable = new Obs();
	private final Observable cancelledObservable = new Obs();

	private final FileTransferStatistics statistics = new FileTransferStatistics(this);
	private Status status;
	private File transferredFile;
	private final FileIdentifier id;
	private Exception exception;

	private FileDownloadStatus(ProjectSpace transferringProjectSpace, FileIdentifier id, Status status,
		File transferredFile) {
		this.transferringProjectSpace = transferringProjectSpace;
		this.status = status;
		this.id = id;
		this.transferredFile = transferredFile;
	}

	/**
	 * Return value of the getStatus method.
	 *
	 * @author jfinis
	 */
	public enum Status {
		/**
		 * The file transfer was not yet started.
		 */
		NOT_STARTED,

		/**
		 * The transfer is actively transfering data.
		 */
		TRANSFERING,

		/**
		 * The transfer is finished.
		 */
		FINISHED,

		/**
		 * The transfer was cancelled.
		 */
		CANCELLED,

		/**
		 * If an exception was thrown. The exception can then be retrieved by
		 * calling getException()
		 */
		FAILED
	}

	/**
	 * Constant signaling "not available".
	 */
	public static final int NOT_AVAILABLE = -1;

	/**
	 * Returns the identifier of the file to be downloaded.
	 *
	 * @return the identifier
	 */
	public FileIdentifier getFileIdentifier() {
		return id;
	}

	/**
	 * This is the ultimate method for checking in which "stage" a file transfer
	 * currently is. i.e. if it is still waiting, transferring or finished. See
	 * the enum Status for possible values.
	 *
	 * @return the stage in which the file transfer currently is
	 */
	public Status getStatus() {
		return status;
	}

	/**
	 * Adds an observer that is notified once the transfer is finished. If the
	 * transfer is already finished at the moment when this method is called,
	 * then the observer is instantly notified. The object that is passed to the
	 * observer's update message is this instance of FileTransferStatus
	 *
	 * @param o
	 *            an observer to be notified when the transfer is finished
	 */
	public void addTransferFinishedObserver(Observer o) {
		// Add
		finishedObservable.addObserver(o);

		// Instantly notify if the transfer is already finished
		if (isTransferFinished()) {
			o.update(finishedObservable, this);
		}
	}

	private void addTransferCancelledObserver(Observer o) {
		// Add
		cancelledObservable.addObserver(o);

		// Instantly notify if the transfer is already finished
		if (status == Status.CANCELLED) {
			o.update(cancelledObservable, this);
		}
	}

	/**
	 * Adds an observer which is notified if the transfer fails due to an
	 * exception. The getException method can then be used to retrieve the
	 * thrown exception.
	 *
	 * @param o
	 *            an observer that is notified if the transfer fails
	 */
	public void addTransferFailedObserver(Observer o) {

		failedObservable.addObserver(o);

		// If the transfer has already failed, notify instantly
		if (status == Status.FAILED) {
			o.update(failedObservable, this);
		}
	}

	/**
	 * Adds a default observer that is notified when the transfer fails. This
	 * observer logs the failure.
	 */
	public void addDefaultFailObserver() {
		addTransferFailedObserver(new Observer() {

			public void update(Observable arg0, Object arg1) {
				final FileDownloadStatus status = (FileDownloadStatus) arg1;
				final Exception e = status.getException();
				ModelUtil.logException(Messages.FileDownloadStatus_TransferFailed, e);

			}
		});
	}

	/**
	 * Returns true if the transfer is finished.
	 *
	 * @return Whether the transfer is finished
	 */
	public boolean isTransferFinished() {
		return status == Status.FINISHED;
	}

	/**
	 * Whether the file to be downloaded is on server.
	 *
	 * @return {@code true} if the file is not on the server, {@code false} otherwise
	 */
	public boolean isNotOnServer() {
		return status == Status.FAILED && getException() instanceof FileNotOnServerException;
	}

	/**
	 * Gets the statistics object for this file transfer, which provides useful
	 * information, especially while the transfer is active. It provides
	 * information like the file size, the amount of already transfered bytes
	 * the estimated remaining time and more.
	 *
	 * @return the statistics for this transfer
	 */
	public FileTransferStatistics getStatistics() {
		return statistics;
	}

	/**
	 * Returns the transferred file. If this is a download, then the file is
	 * only available, if the download is finished. If it is not finished yet,
	 * an file transfer exception is thrown.
	 *
	 * @return the transferred file or a FileTransferException exception if the
	 *         file is not yet transferred.
	 * @throws FileTransferException
	 *             if the file is not yet fully transferred
	 */
	public File getTransferredFile() throws FileTransferException {
		if (isNotOnServer()) {
			throw new FileNotOnServerException(MessageFormat.format(
				Messages.FileDownloadStatus_FileNotOnServer,
				id.getIdentifier()));
		} else if (!isTransferFinished()) {
			throw new FileTransferException(MessageFormat.format(
				Messages.FileDownloadStatus_TransferNotFinishedYet,
				id.getIdentifier()));
		}
		return transferredFile;
	}

	/**
	 * Similar to {@link #getTransferredFile()}, but this method blocks the
	 * client thread.
	 *
	 * @param block
	 *            whether to block or not
	 * @return the transferred file
	 * @throws FileTransferException
	 *             in case of an error during transfer
	 */
	public File getTransferredFile(boolean block) throws FileTransferException {
		if (!isTransferFinished() && block) {
			/**
			 * TODO: Double-check this code
			 */
			final Observer observer = new Observer() {
				public void update(Observable arg0, Object arg1) {
					synchronized (this) {
						// TODO: notify should be sufficient here
						notifyAll();
					}
				}
			};
			addTransferFailedObserver(observer);
			addTransferFinishedObserver(observer);
			addTransferCancelledObserver(observer);
			try {
				synchronized (observer) {
					observer.wait();
				}
			} catch (final InterruptedException e) {
				throw new FileTransferException(Messages.FileDownloadStatus_BlockedGetInitFailed, e);
			}
		}
		return getTransferredFile();
	}

	/**
	 * Returns the project space which started this file transfer.
	 *
	 * @return the project space owning this file transfer
	 */
	public ProjectSpace getTransferringProjectSpace() {
		return transferringProjectSpace;
	}

	/**
	 * Returns the exception that caused the download to fail, if the status ==
	 * FAILED. Otherwise, returns null
	 *
	 * @return the exception that caused the failure or null if not failed
	 */
	public Exception getException() {
		return exception;
	}

	/**
	 * Called internally if the transfer is canceled.
	 */
	void transferCancelled() {
		if (status == Status.FINISHED) {
			return;
		}
		statistics.registerStop();
		status = Status.CANCELLED;
		cancelledObservable.notifyObservers(this);
	}

	/**
	 * Called internally when the transfer is started.
	 *
	 * @param fileSize
	 *            the file size
	 * @throws FileTransferException
	 *             if the transfer has already been started
	 */
	void transferStarted(int fileSize) throws FileTransferException {
		if (status != Status.NOT_STARTED) {
			throw new FileTransferException(Messages.FileDownloadStatus_CannotStartJob + status.name());
		}
		statistics.registerStart(fileSize);
		status = Status.TRANSFERING;
	}

	/**
	 * Called internally when the transfer is finished.
	 *
	 * @param result
	 *            the resulting file in the cache
	 */
	void transferFinished(File result) {
		status = Status.FINISHED;
		transferredFile = result;
		statistics.registerStop();
		finishedObservable.notifyObservers(this);
	}

	/**
	 * Called internally if the transfer fails.
	 *
	 * @param ex
	 *            the exception that caused the failure
	 */
	void transferFailed(Exception ex) {
		status = Status.FAILED;
		statistics.registerStop();
		exception = ex;
		failedObservable.notifyObservers(this);
	}

	/**
	 * This observerable is always changed, so notifying will always notify
	 * Observers.
	 *
	 * @author jfinis
	 */
	private static class Obs extends Observable {

		@Override
		public void notifyObservers(Object arg) {
			super.setChanged();
			super.notifyObservers(arg);
		}
	}

	/**
	 * This factory class creates the different possible download stats.
	 *
	 * @author jfinis
	 */
	static class Factory {

		/**
		 * Creates an already finished download status (status FINISHED).
		 *
		 * @param p
		 *            the project space containing the download
		 * @param id
		 *            the identifier of the download
		 * @param transferredFile
		 *            the file where the download can be found
		 * @return the created status object
		 */
		public static FileDownloadStatus createAlreadyFinished(ProjectSpace p, FileIdentifier id,
			File transferredFile) {
			return new FileDownloadStatus(p, id, Status.FINISHED, transferredFile);
		}

		/**
		 * Creates a new download status which is initially in the NOT_STARTED
		 * state.
		 *
		 * @param p
		 *            the project space containing the download
		 * @param id
		 *            the identifier of the file to be downloaded
		 * @return the created status object
		 */
		public static FileDownloadStatus createNew(ProjectSpace p, FileIdentifier id) {
			return new FileDownloadStatus(p, id, Status.NOT_STARTED, null);
		}
	}

}
