package nxm.sys.net;

import nxm.sys.lib.Table;

/** Provides the interface for all objects that are capable of providing data
    in response to an HTTP request.  Objects should override the handleRequest
    method to fill in the HPage with the appropriate response.

    @author Jeff Schoen
    @author J. Czechowski IV
 */
public class HSource {
  /** name of this resource */
  public String name;
  /** HTTP Server for this resource */
  public HServer server;

  /** Creates a new instance without the name set. <br><br>
      <b>Since NeXtMidas 2.1.1</b>: Use <code>HSource(String)</code>.
   */
  public HSource() { }

  /** Creates a new instance.
      @param name The name to use.
   */
  public HSource(String name) {
    this.name = (name.startsWith("/"))? name.substring(1) : name;
  }

  /** Returns the name of this resource
   *  @return name of this resource */
  public String getName() {
    return "/"+name;
  }

  /** Returns true if this data source can handle the request for the specified uri.
   *  @param uri string form of uniform resource identifier
   *  @return true if this data source can handle the request
   */
  public boolean canHandleRequest (String uri) {
    String rname = getName();
    if (!uri.startsWith(rname)) return false;
    int lr = rname.length(), lu = uri.length();
    if (rname.charAt(lr-1)=='/') return true;
    return (lu<=lr || uri.charAt(lr)=='/' || uri.charAt(lr)=='?');
  }

  /** Invoked to write the data from this source into the specified HPage.
      @param uri The Request string containing the request parameters.
      @param hp The HPage to write the data into.
  */
  public void handleRequest (String uri, HPage hp) {
    hp.open();
    hp.close();
  }

  /** Parses a URI to get any parameters. Examples:
      <pre>
        getParameters("http://localhost/")              = { }
        getParameters("http://localhost/?one=1")        = {ONE="1"}
        getParameters("http://localhost/?one=1&two=2")  = {ONE="1",TWO="2"}
        getParameters("http://localhost/?str=a+b+c")    = {STR="a b c"}
      </pre>
      @param uri The full uri.
      @return The parameters attached to the URI.
      @since NeXtMidas 2.1.1
   */
  protected static final Table getParameters (String uri) {
    return getParameters(uri, null);
  }

  /** Parses a URI to get any parameters. */
  static final Table getParameters (String uri, Table tbl) { // package-private, used by HSource & HPage
    if (tbl == null) tbl = new Table();
    if (uri == null) return tbl;

    int start = uri.indexOf('?');
    if (start < 0) return tbl;

    String[] params = uri.substring(start + 1).split("[&]");
    for (int i = 0; i < params.length; i++) {
      String[] param = params[i].split("[=]");
      String   name  = param[0].toUpperCase();
      if (param.length > 1) {
        String value = param[1].replace('+',' ').replaceAll("[%]20", " ");
        tbl.setKey(name, value);
      }
    }
    return tbl;
  }

  /** Sets the HTTP Server for this resource
   *  @param server the HTTP Server for this resource
   */
  public void setServer (HServer server) {
    this.server = server;
  }

}
