/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

package foam.nanos.http;

import foam.box.*;
import foam.core.*;
import foam.core.FObject;
import foam.lib.json.JSONParser;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader;
import java.nio.CharBuffer;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;

@SuppressWarnings("serial")
public class ServiceWebAgent
  implements WebAgent
{
  protected Object service_;
  protected Box    skeleton_;
//  protected X      x_;

  public ServiceWebAgent(Object service, Box skeleton) {
    service_  = service;
    skeleton_ = skeleton;
  }

/*
  public X    getX() { return x_; }
  public void setX(X x) {
    x_ = x;
    if ( skeleton_ instanceof ContextAware )
      ((ContextAware) skeleton_).setX(x);
  }
*/

/*
  @Override
  public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    resp.setHeader("Access-Control-Allow-Origin", "*");
    resp.setStatus(resp.SC_OK);
    resp.flushBuffer();
  }
*/

  public void execute(X x) {
    try {
      HttpServletRequest  req            = (HttpServletRequest)  x.get(HttpServletRequest.class);
      HttpServletResponse resp           = (HttpServletResponse) x.get(HttpServletResponse.class);
      PrintWriter         out            = (PrintWriter) x.get(PrintWriter.class);
      CharBuffer          buffer_        = CharBuffer.allocate(65535);
      Reader              reader         = req.getReader();
      int                 count          = reader.read(buffer_);
      X                   requestContext = x.put("httpRequest", req).put("httpResponse", resp);

      resp.setHeader("Access-Control-Allow-Origin", "*");
      buffer_.rewind();

      FObject result = requestContext.create(JSONParser.class).parseString(buffer_.toString());

      if ( result == null ) {
        resp.setStatus(resp.SC_BAD_REQUEST);
        System.err.println("Failed to parse request");
        out.print("Failed to parse request");
        out.flush();
        return;
      }

      if ( ! ( result instanceof foam.box.Message ) ) {
        resp.setStatus(resp.SC_BAD_REQUEST);
        System.err.println("Expected instance of foam.box.Message");
        out.print("Expected instance of foam.box.Message");
        out.flush();
        return;
      }

      // TODO: make skeleton_.send() take x instead
      if ( service_ instanceof ContextAware )
        ((ContextAware) service_).setX(x);

      foam.box.Message msg = (foam.box.Message) result;
      skeleton_.send(msg);
    } catch (Throwable t) {
      throw new RuntimeException(t);
    }
  }

/*
  public void doOptions(HttpServletRequest req, HttpServletResponse resp)
    throws IOException, ServletException
  {
    resp.setHeader("Access-Control-Allow-Origins", "*");
    resp.setHeader("Access-Control-Allow-Methods", "GET POST");
    resp.setHeader("Access-Control-Allow-Headers", "Content-Type");
    super.doOptions(req, resp);
  }
  */
}

@@ -2153,33 +2153,56 @@
 to parse request
-%22
+: %22 + buffer_.toString()
 );%0A        out.f

Add details to parse failure error.