package aQute.bnd.service;

import java.io.*;
import java.net.*;
import java.util.*;

import aQute.bnd.version.*;

/**
 * A Repository Plugin abstract a bnd repository. This interface allows bnd to
 * find programs from their bsn and revisions from their bsn-version
 * combination. It is also possible to put revisions in a repository if the
 * repository is not read only.
 */
public interface RepositoryPlugin {
	/**
	 * Options used to steer the put operation
	 */
	class PutOptions {
		public String	BUNDLE	= "application/vnd.osgi.bundle";
		public String	LIB		= "application/vnd.aQute.lib";

		/**
		 * The <b>SHA1</b> digest of the artifact to put into the repository.
		 * When specified the digest of the <b>fetched</b> artifact will be
		 * calculated and verified against this digest, <b>before</b> putting
		 * the artifact into the repository. </p> An exception is thrown if the
		 * specified digest and the calculated digest do not match.
		 */
		public byte[]	digest	= null;

		/**
		 * Specify the mime type of the importing stream. This can be either
		 * {@link #BUNDLE} or {@link #LIB}. If left open, it is up to the
		 * repository to guess the content type.
		 */
		public String	type;
	}

	PutOptions	DEFAULTOPTIONS	= new PutOptions();

	/**
	 * Results returned by the put operation
	 */
	class PutResult {
		/**
		 * A (potentially public) uri to the revision as it was put in the
		 * repository.<br/>
		 * <br/>
		 * This can be a URI to the given artifact (when it was put into the
		 * repository). This does not have to be a File URI!
		 */
		public URI		artifact	= null;

		/**
		 * The <b>SHA1</b> digest of the artifact as it was put into the
		 * repository.<br/>
		 * <br/>
		 * This can be null and it can differ from the input digest if the
		 * repository rewrote the stream for optimization reason. If the
		 */
		public byte[]	digest		= null;
	}

	/**
	 * Put an artifact (from the InputStream) into the repository.<br/>
	 * <br/>
	 * There is NO guarantee that the artifact on the input stream has not been
	 * modified after it's been put in the repository since that is dependent on
	 * the implementation of the repository (see
	 * {@link RepositoryPlugin.PutOptions#allowArtifactChange}).
	 * 
	 * @param stream
	 *            The input stream with the artifact
	 * @param options
	 *            The put options. See {@link RepositoryPlugin.PutOptions}, can
	 *            be {@code null}, which will then take the default options like
	 *            new PutOptions().
	 * @return The result of the put, never null. See
	 *         {@link RepositoryPlugin.PutResult}
	 * @throws Exception
	 *             When the repository root directory doesn't exist, when the
	 *             repository is read-only, when the specified checksum doesn't
	 *             match the checksum of the fetched artifact (see
	 *             {@link RepositoryPlugin.PutOptions#digest}), when the
	 *             implementation wants to modify the artifact but isn't allowed
	 *             (see {@link RepositoryPlugin.PutOptions#allowArtifactChange}
	 *             ), or when another error has occurred.
	 */
	PutResult put(InputStream stream, PutOptions options) throws Exception;

	/**
	 * The caller can specify any number of DownloadListener objects that are
	 * called back when a download is finished (potentially before the get
	 * method has returned).
	 */

	interface DownloadListener {
		/**
		 * Called when the file is successfully downloaded from a remote
		 * repository.
		 * 
		 * @param file
		 *            The file that was downloaded
		 * @throws Exception
		 *             , are logged and ignored
		 */
		void success(File file) throws Exception;

		/**
		 * Called when the file could not be downloaded from a remote
		 * repository.
		 * 
		 * @param file
		 *            The file that was intended to be downloaded.
		 * @throws Exception
		 *             , are logged and ignored
		 */
		void failure(File file, String reason) throws Exception;

		/**
		 * Can be called back regularly before success/failure but never after.
		 * Indicates how far the download has progressed in percents. Since
		 * downloads can be restarted, it is possible that the percentage
		 * decreases.
		 * 
		 * @param file
		 *            The file that was intended to be downloaded
		 * @param percentage
		 *            Percentage of file downloaded (can go down)
		 * @return true if the download should continue, fails if it should be
		 *         canceled (and fail)
		 * @throws Exception
		 *             , are logged and ignored
		 */
		boolean progress(File file, int percentage) throws Exception;
	}

	/**
	 * Return a URL to a matching version of the given bundle.
	 * <p/>
	 * If download listeners are specified then the returned file is not
	 * guaranteed to exist before a download listener is notified of success or
	 * failure. The callback can happen before the method has returned. If the
	 * returned file is null then download listeners are not called back.
	 * <p/>
	 * The intention of the Download Listeners is to allow a caller to obtain
	 * references to files that do not yet exist but are to be downloaded. If
	 * the downloads were done synchronously in the call, then no overlap of
	 * downloads could take place.
	 * 
	 * @param bsn
	 *            Bundle-SymbolicName of the searched bundle
	 * @param version
	 *            Version requested
	 * @param listeners
	 *            Zero or more download listener that will be notified of the
	 *            outcome.
	 * @return A file to the revision or null if not found
	 * @throws Exception
	 *             when anything goes wrong, in this case no listeners will be
	 *             called back.
	 */
	File get(String bsn, Version version, Map<String,String> properties, DownloadListener... listeners)
			throws Exception;

	/**
	 * Answer if this repository can be used to store files.
	 * 
	 * @return true if writable
	 */
	boolean canWrite();

	/**
	 * Return a list of bsns that are present in the repository.
	 * 
	 * @param pattern
	 *            A <ahref="https://en.wikipedia.org/wiki/Glob_%28programming%29">glob pattern</a>
	 *            to be matched against bsns present in the repository, or {@code null}.
	 * @return A list of bsns that match the pattern parameter or all if pattern
	 *         is null; repositories that do not support browsing or querying
	 *         should return an empty list.
	 * @throws Exception
	 */
	List<String> list(String pattern) throws Exception;

	/**
	 * Return a list of versions.
	 * 
	 * @throws Exception
	 */

	SortedSet<Version> versions(String bsn) throws Exception;

	/**
	 * @return The name of the repository
	 */
	String getName();

	/**
	 * Return a location identifier of this repository
	 */

	String getLocation();
}
