package click.runtime;

import java.io.IOException;
import java.util.Vector;

import jist.runtime.JistAPI;


public interface ClickInterface extends JistAPI.DoNotRewrite {

  //////////////////////////////////////////////////
  // constants
  //

  static final int IFID_KERNELTAP = 31;

  static final int IFID_FIRST = 0;

  static final int IFID_LAST = 32;


  public static final int SIMCLICK_PTYPE_UNKNOWN = 0;

  public static final int SIMCLICK_PTYPE_ETHER = 1;

  public static final int SIMCLICK_PTYPE_IP = 2;

  public static final int SIMCLICK_PTYPE_WIFI = 3;

  public static final int SIMCLICK_PTYPE_WIFI_EXTRA = 4;

  
  
  /**
   * Returns a String describing the socket's destination address and port.
   *
   * @return Socket description.
   */
  public abstract String name();

  /**
   * Gets a String containing the router's configuration.
   *
   * @return Router configuration.
   * @throws NoSuchHandlerException    If there is no configuration read handler.
   * @throws HandlerErrorException     If the handler returned an error.
   * @throws PermissionDeniedException If the router would not let us access the handler.
   * @throws IOException               If there was some other error accessing
   *                                   the handler (e.g., there was a stream or socket error, the
   *                                   ControlSocket returned an unknwon unknown error code, or the
   *                                   response could otherwise not be understood).
   * @see #getRouterFlatConfig
   * @see #getConfigElementNames
   */
  public abstract String getRouterConfig() throws ClickException, IOException;

  /**
   * Gets a String containing the router's flattened configuration.
   *
   * @return Flattened router configuration.
   * @throws NoSuchHandlerException    If there is no flattened configuration read handler.
   * @throws HandlerErrorException     If the handler returned an error.
   * @throws PermissionDeniedException If the router would not let us access the handler.
   * @throws IOException               If there was some other error accessing
   *                                   the handler (e.g., there was a stream or socket error, the
   *                                   ControlSocket returned an unknwon unknown error code, or the
   *                                   response could otherwise not be understood).
   * @see #getRouterConfig
   * @see #getConfigElementNames
   */
  public abstract String getRouterFlatConfig() throws ClickException,
      IOException;

  /**
   * Gets a String containing the router's version.
   *
   * @return Version string.
   * @throws NoSuchHandlerException    If there is no version read handler.
   * @throws HandlerErrorException     If the handler returned an error.
   * @throws PermissionDeniedException If the router would not let us access the handler.
   * @throws IOException               If there was some other error accessing
   *                                   the handler (e.g., there was a stream or socket error, the
   *                                   ControlSocket returned an unknwon unknown error code, or the
   *                                   response could otherwise not be understood).
   * @see String
   */
  public abstract String getRouterVersion() throws ClickException, IOException;

  /**
   * Gets the names of elements in the current router configuration.
   *
   * @return Vector of Strings of the element names.
   * @throws NoSuchHandlerException    If there is no element list read handler.
   * @throws HandlerErrorException     If the handler returned an error.
   * @throws PermissionDeniedException If the router would not let us access the handler.
   * @throws IOException               If there was some other error accessing
   *                                   the handler (e.g., there was a stream or socket error, the
   *                                   ControlSocket returned an unknwon unknown error code, or the
   *                                   response could otherwise not be understood).
   * @see #getElementHandlers
   * @see #getRouterConfig
   * @see #getRouterFlatConfig
   */
  public abstract Vector getConfigElementNames() throws ClickException,
      IOException;

  /**
   * Gets the names of element types that the router knows about.
   *
   * @return Vector of Strings of the element names.
   * @throws NoSuchHandlerException    If there is no element list read handler.
   * @throws HandlerErrorException     If the handler returned an error.
   * @throws PermissionDeniedException If the router would not let us access the handler.
   * @throws IOException               If there was some other error accessing
   *                                   the handler (e.g., there was a stream or socket error, the
   *                                   ControlSocket returned an unknwon unknown error code, or the
   *                                   response could otherwise not be understood).
   */
  public abstract Vector getRouterClasses() throws ClickException, IOException;

  /**
   * Gets the names of packages that the router knows about.
   *
   * @return Vector of Strings of the package names.
   * @throws NoSuchHandlerException    If there is no element list read handler.
   * @throws HandlerErrorException     If the handler returned an error.
   * @throws PermissionDeniedException If the router would not let us access the handler.
   * @throws IOException               If there was some other error accessing
   *                                   the handler (e.g., there was a stream or socket error, the
   *                                   ControlSocket returned an unknwon unknown error code, or the
   *                                   response could otherwise not be understood).
   */
  public abstract Vector getRouterPackages() throws ClickException, IOException;

  /**
   * Gets the names of the current router configuration requirements.
   *
   * @return Vector of Strings of the package names.
   * @throws NoSuchHandlerException    If there is no element list read handler.
   * @throws HandlerErrorException     If the handler returned an error.
   * @throws PermissionDeniedException If the router would not let us access the handler.
   * @throws IOException               If there was some other error accessing
   *                                   the handler (e.g., there was a stream or socket error, the
   *                                   ControlSocket returned an unknwon unknown error code, or the
   *                                   response could otherwise not be understood).
   * @see #getRouterConfig
   * @see #getRouterFlatConfig
   */
  public abstract Vector getConfigRequirements() throws ClickException,
      IOException;

  /**
   * Gets the information about an element's handlers in the current
   * router configuration.
   *
   * @param el The element name.
   * @return Vector of HandlerInfo structures.
   * @throws NoSuchElementException    If there is no such element in the current configuration.
   * @throws HandlerErrorException     If the handler returned an error.
   * @throws PermissionDeniedException If the router would not let us access the handler.
   * @throws IOException               If there was some other error accessing
   *                                   the handler (e.g., there was a stream or socket error, the
   *                                   ControlSocket returned an unknwon unknown error code, or the
   *                                   response could otherwise not be understood).
   * @see #HandlerInfo
   * @see #getConfigElementNames
   * @see #getRouterConfig
   * @see #getRouterFlatConfig
   */
  public abstract Vector getElementHandlers(String elementName)
      throws ClickException, IOException;

  /**
   * Returns the result of reading an element's handler.
   *
   * @param elementName The element name.
   * @param handlerName The handler name.
   * @return Char array containing the data.
   * @throws NoSuchHandlerException    If there is no such read handler.
   * @throws NoSuchElementException    If there is no such element in the current configuration.
   * @throws HandlerErrorException     If the handler returned an error.
   * @throws PermissionDeniedException If the router would not let us access the handler.
   * @throws IOException               If there was a stream or socket error.
   * @throws ClickException            If there was some other error
   *                                   accessing the handler (e.g., the ControlSocket returned an unknown
   *                                   unknown error code, or the response could otherwise not be understood).
   * @see #checkHandler
   * @see #write
   * @see #getConfigElementNames
   * @see #getElementHandlers
   */
  public abstract char[] read(String elementName, String handlerName)
      throws ClickException, IOException;

  public abstract String readString(String el, String handler)
      throws ClickException, IOException;

  public abstract String readString(HandlerInfo handler) throws ClickException, IOException;

  /**
   * Writes data to an element's handler.
   *
   * @param elementName The element name.
   * @param handlerName The handler name.
   * @param data        Char array containing the data.
   * @throws NoSuchHandlerException    If there is no such write handler.
   * @throws NoSuchElementException    If there is no such element in the current configuration.
   * @throws HandlerErrorException     If the handler returned an error.
   * @throws PermissionDeniedException If the router would not let us access the handler.
   * @throws IOException               If there was a stream or socket error.
   * @throws ClickException            If there was some other error
   *                                   accessing the handler (e.g., the ControlSocket returned an unknown
   *                                   unknown error code, or the response could otherwise not be understood).
   * @see #checkHandler
   * @see #write
   * @see #getConfigElementNames
   * @see #getElementHandlers
   */
  public abstract int write(String elementName, String handlerName, String data)
      throws ClickException, IOException;

  public abstract int write(HandlerInfo info, String data)
      throws ClickException, IOException;

  /**
   * Send packet to click
   *
   * @param ifid interface id
   * @param type encap type
   * @param data data
   * @param txfeedback whether it is a tx feedback
   * @throws ClickException
   * @throws IOException
   */
  public void send(int ifid, int type, byte[] data, boolean txfeedback)
    throws ClickException, IOException;

  /**
   * Handles callbacks from Click.
   *
   * @author kurth
   */
  public static interface CallbackHandler {

    /**
     * A packet arrived in Click.
     *
     * @param ifid interface id
     * @param data data
     * @param type encap type
     * @throws ClickException
     */
    public void recvFromClick(int ifid, byte[] data, int type);
  }

  public void close();

}