package aQute.remote.api;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.osgi.framework.dto.BundleDTO;
import org.osgi.framework.dto.FrameworkDTO;
import org.osgi.framework.wiring.dto.BundleRevisionDTO;

/**
 * An agent runs on remote OSGi framework and provides the means to control this
 * framework. This API can also be used to install a framework before an agent
 * is started. Such a pre-agent is called an Envoy. An Envoy implements {@link
 * #createFramework(String, Collection, Map)} and {@link #isEnvoy()} only but
 * switches to the agent API once the framework is installed.
 */
public interface Agent {

	/**
	 * The default port. The port can be overridden with the System/framework
	 * property {$value {@link #AGENT_SERVER_PORT_KEY}.
	 */
	int DEFAULT_PORT = 29998;

	/**
	 * The property key to set the agent's port.
	 */
	String AGENT_SERVER_PORT_KEY = "aQute.agent.server.port";

	/**
	 * The pattern for a server port specification: {@code [<interface>:]<port>}
	 * .
	 */
	Pattern	PORT_P			= Pattern.compile("(?:([^:]+):)?(\\d+)");
	/**
	 * The port for attaching to a remote Gogo CommandSession
	 */
	int		COMMAND_SESSION	= -1;

	/**
	 * The port for having no redircet of IO
	 */
	int NONE = 0;

	/**
	 * The port for System.in, out, err redirecting.
	 */
	int CONSOLE = 1;

	/**
	 * An Envoy is an agent that can install a framework (well, -runpath) and
	 * launch it with an Agent. An envoy can only handle this method and {@link
	 * #createFramework(String, Collection, Map)} so other methods should not be
	 * called. This rather awkward model is necessary so that we do not have to
	 * reconnect to the actual agent. @return true if this is a limited envoy,
	 * otherwise true for a true Agent.
	 */
	boolean isEnvoy();

	/**
	 * Get the Bundles for the given ids. If no ids are given, all bundles are
	 * returned.
	 */
	List<BundleDTO> getBundles(long... bundleId) throws Exception;

	/**
	 * Get the Bundle Revisions for the given ids. If no ids are given, the
	 * revisions for all bundles must be returned.
	 */

	List<BundleRevisionDTO> getBundleRevisons(long... bundleId) throws Exception;

	/**
	 * Get the framework DTO
	 */
	FrameworkDTO getFramework() throws Exception;

	/**
	 * Install a new bundle at the given bundle location. The SHA identifies the
	 * file and should be retrievable through {@link Supervisor#getFile(String)}
	 * . @param location the bundle location @param sha the sha of the bundle's
	 * JAR @return A Bundle DTO
	 */
	BundleDTO install(String location, String sha) throws Exception;

	/**
	 * Install a new bundle at the given location using a url to get the stream.
	 * <p>
	 * <b>NOTICE:</b> this method makes assumptions about the target e.g. that
	 * it will be able to use out-of-band communication to read from the URL and
	 * have the necessary url handlers to open the URL stream.
	 * </p>
	 *
	 * @param location
	 *            the bundle location
	 * @param url
	 *            url of the bundle that can retrived using url.openStream()
	 * @return A bundle DTO
	 */
	BundleDTO installFromURL(String location, String url) throws Exception;

	/**
	 * Start a number of bundles @param id the bundle ids @return any errors
	 * that occurred
	 */
	String start(long... id) throws Exception;

	/**
	 * Stop a number of bundles @param id the bundle ids @return any errors that
	 * occurred
	 */
	String stop(long... id) throws Exception;

	/**
	 * Uninstall a number of bundles @param id the bundle ids @return any errors
	 * that occurred
	 */

	String uninstall(long... id) throws Exception;

	/**
	 * Update the bundles in the framework. Each agent compares this map against
	 * a map of installed bundles. The map maps a bundle location to SHA. Any
	 * differences are reflected in the installed bundles. That is, a change in
	 * the SHA will update, a new entry will install, and a removed entry will
	 * uninstall. This is the preferred way to keep the remote framework
	 * synchronized since it is idempotent. @param bundles the bundles to update
	 */
	String update(Map<String,String> bundles) throws Exception;

	/**
	 * Updates a single bundle by id in the framework. The SHA identifies the
	 * file and should be retrievable through {@link Supervisor#getFile(String)}
	 *
	 * @param location
	 *            the bundle location
	 * @param sha
	 *            the sha of the bundle
	 * @return any errors that occurred
	 */
	String update(long id, String sha) throws Exception;

	/**
	 * Updates a single bundle from a url
	 * <p>
	 * <b>NOTICE:</b> this method makes assumptions about the target e.g. that
	 * it will be able to use out-of-band communication to read from the URL and
	 * have the necessary url handlers to open the URL stream.
	 * </p>
	 *
	 * @param id
	 *            bundle to update
	 * @param url
	 *            location of bundle contents
	 * @return any errors that occurred
	 */
	String updateFromURL(long id, String url) throws Exception;

	/**
	 * Redirect I/O from port. Port can be {@link #CONSOLE},
	 * {@link #COMMAND_SESSION}, {@link #NONE}, or a TCP Telnet port. @param
	 * port the port to redirect from @return if the redirection was changed
	 */
	boolean redirect(int port) throws Exception;

	/**
	 * Send a text to the potentially redirected stdin stream so that remotely
	 * executing code will read it from an InputStream. @param s text that
	 * should be read as input @return true if this was redirected
	 */
	boolean stdin(String s) throws Exception;

	/**
	 * Execute a remote command on Gogo (if present) and return the
	 * result. @param cmd the command to execute @return the result
	 */
	String shell(String cmd) throws Exception;

	/**
	 * Get the remote's system's System properties @return the remote systems
	 * properties
	 */
	Map<String,String> getSystemProperties() throws Exception;

	/**
	 * This method is only implemented in the Envoy (the pre-Agent). It is meant
	 * to install a -runpath before the framework runs. An Envoy can actally
	 * created multiple independent frameworks. If this framework already
	 * existed, and the given parameters are identical, that framework will be
	 * used for the aget that will take over. Otherwise the current framework is
	 * stopped and a new framework is started. @param name the name of the
	 * framework @param runpath the runpath the install @param properties the
	 * framework properties @return if this created a new framework
	 */
	boolean createFramework(String name, Collection<String> runpath, Map<String,Object> properties) throws Exception;

	/**
	 * Abort the remote agent. The agent should send an event back and die. This
	 * is an async method.
	 */
	void abort() throws Exception;

	/**
	 * Ping the remote agent to see if it is still alive.
	 */
	boolean ping();
}

@@ -4327,39 +4327,18 @@
  @param 
-location%0A%09 *           
+id
  the bun
@@ -4337,32 +4337,26 @@
  the bundle 
-location
+id
 %0A%09 * @param 
@@ -4358,31 +4358,16 @@
 aram sha
-%0A%09 *           
  the sha

Fix javadoc warnings.